MEF 肯定会帮助您,但不仅限于此。您必须使用ISerializationSurrogate。您可以在此处找到以下内容的大部分解释。
因此,给定数据包接口的以下定义:
public interface IPacket
{
string GetInfo();
}
您有以下实现,驻留在它们自己的程序集中:
[Export(typeof(IPacket))]
class FirstPacket : IPacket
{
public FirstPacket()
{
Name = "Joe";
}
public string Name { get; set; }
public string GetInfo()
{
return "Name: " + Name;
}
}
[Export(typeof(IPacket))]
class SecondPacket : IPacket
{
public SecondPacket()
{
Measurement = 42.42m;
}
public decimal Measurement { get; set; }
public string GetInfo()
{
return "Measurement: " + Measurement;
}
}
现在我们将定义另一个接口,例如:
public interface IPacketSurrogateProvider
{
void AddSurrogate(SurrogateSelector toSelector);
}
以及匹配的实现,在定义具体数据包的同一个程序集中:
[Export(typeof(IPacketSurrogateProvider))]
class FirstPacketSurrogateProvider : IPacketSurrogateProvider, ISerializationSurrogate
{
public void AddSurrogate(SurrogateSelector toSelector)
{
toSelector.AddSurrogate(typeof(FirstPacket), new StreamingContext(StreamingContextStates.All), this);
}
public void GetObjectData(object obj, SerializationInfo info, StreamingContext context)
{
info.AddValue("Name", ((FirstPacket)obj).Name);
}
public object SetObjectData(object obj, SerializationInfo info, StreamingContext context, ISurrogateSelector selector)
{
((FirstPacket)obj).Name = info.GetString("Name");
return obj;
}
}
[Export(typeof(IPacketSurrogateProvider))]
class SecondPacketSurrogateProvider : IPacketSurrogateProvider, ISerializationSurrogate
{
public void AddSurrogate(SurrogateSelector toSelector)
{
toSelector.AddSurrogate(typeof(SecondPacket), new StreamingContext(StreamingContextStates.All), this);
}
public void GetObjectData(object obj, SerializationInfo info, StreamingContext context)
{
info.AddValue("Measurement", ((SecondPacket)obj).Measurement);
}
public object SetObjectData(object obj, SerializationInfo info, StreamingContext context, ISurrogateSelector selector)
{
((SecondPacket)obj).Measurement = info.GetDecimal("Measurement");
return obj;
}
}
现在,在一个程序集中,它确实引用了带有接口的程序集,但没有引用带有实现的程序集,并且具有与上述两者相同的部署文件夹:
public static void Test()
{
var container = new CompositionContainer(new DirectoryCatalog(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)));
var packets = container.GetExportedValues<IPacket>().ToArray();
var packetSurrogateProviders = container.GetExportedValues<IPacketSurrogateProvider>();
var surrogateSelector = new SurrogateSelector();
foreach (var provider in packetSurrogateProviders)
{
provider.AddSurrogate(surrogateSelector);
}
var deserializedPackets = new IPacket[] { };
using (var stream = new MemoryStream())
{
var formatter = new BinaryFormatter {SurrogateSelector = surrogateSelector};
formatter.Serialize(stream, packets);
stream.Position = 0;
deserializedPackets = (IPacket[])formatter.Deserialize(stream);
}
foreach (var packet in deserializedPackets)
{
Console.WriteLine("Packet info: {0}", packet.GetInfo());
}
}
产生:
数据包信息:姓名:Joe
数据包信息:测量:42.42