我是 MEF 的新手并想知道为我的设置将它们组合在一起的正确方法是什么,因为我读过的所有基本教程都没有涵盖序列化方面的内容。
我有一个由模块组成的系统(所有模块都派生自一个公共(public)基类型 B
)。在运行时模块被创建(= 从类型列表中挑选出来并发送到 Activator
)并动态删除(通过用户输入)。这些模块的实例存储在列表结构(List<B>
)中,并且模块类型都是可序列化的。所以为了持久化/检索模块的状态,这个列表只是被序列化/反序列化。
我现在要做的是将不同类型的模块打包到不同的程序集中,以实现更好的可扩展性。但是,“未知类型”(因此意味着 MEF 发现的程序集类型)的反序列化似乎不起作用。所以我想到了一个像这样工作的解决方案;假设一个包装模块创建的 API 接口(interface):
interface IModulePlugin {
string FullyQualifiedName {get; }
Type ModuleType {get; }
B GetInstance(); // create new instance (Activator)
B GetInstance(Stream s); // recreate instance by deserialization
Stream Serialize();
}
导入后现在...
[ImportMany(typeof(IModulePlugin))]
List<IModulePlugin> plugins;
...用列表元素注册(明确的)名称和模块类型,例如字典,以便在序列化期间将名称与模块的数据一起存储。
然后反序列化的过程会变成这样:
- 读取名称并尝试检索相应的插件
- 调用
GetInstance()
针对具有反序列化数据的插件 - ...
是这样吗?在我看来似乎有点复杂,我不确定这是否真的有效。这个想法是将序列化所需的知识放到模块/插件中。然而,如果插件必须相互依赖(如“核心”插件和“核心扩展”插件)或版本控制到位,它会变得更加复杂。
(顺便说一句:我在 .NET 4.5 和 BinaryFormatter 上使用 C# 5)
感谢您的回复!
最佳答案
我会评论,但我没有足够的声誉。看到你的问题是去年的......我想知道你找到了什么解决方案以及你选择了什么解决方案。
编辑:也许这会对某人有所帮助。
我所做的是:从 MEF 组件中获取我想要保存的类型列表,并通过 System.Runtime.Serialization.DataContractSerializer 保存它们。 它具有您可以在构造函数中设置的 Knowntypes 属性。
MEF_ComponenentList.Select(item => item.GetType());
public static void SerializeSomething<T>(T objToSave, string fileToSaveTo, IEnumerable<Type> KnownTypes = null)
{
var ser = new System.Runtime.Serialization.DataContractSerializer(typeof(T));
var settings = new XmlWriterSettings { Indent = true };
System.IO.File.Delete(fileToSaveTo);
if (KnownTypes != null)
{
var sum = ser.KnownTypes.Concat(KnownTypes);
ser = new System.Runtime.Serialization.DataContractSerializer(typeof(T), sum);
}
using (var writer = XmlWriter.Create(fileToSaveTo, settings))
{
ser.WriteObject(writer, objToSave);
}
}
你必须小心你公开的属性等......或者你必须使用 IgnoreDataMember。
关于c# - MEF 和序列化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23085210/