我们目前在我们的应用程序中使用protobuf-net,我希望在反序列化后注入属性。
例如,如果serialize对象具有名为DataFactory
namespace Project
{
[ProtoContract]
public class Model
{
[ProtoMember]
public String Name { get; set; }
[ProtoIgnore]
public IDataFactory DataFactory { get; set; }
}
}
在Spring.config
文件中,您有接口的定义:
<object id="IDataFactory" type="Project.Impl.DataFactory, Project" />
我怎么说(或关联)反序列化设置属性IDataFactory
。
这是一个悬而未决的问题,所以请随时提出想法或建议。
我认为将protobuf-net库的对象实例化器挂钩以便它使用Spring.NET创建对象然后设置属性会很棒。你怎么认为我能做到这一点?
谢谢!
理想情景
我想在Spring.net
反序列化之后由protobuf
直接设置DataFactory。
Model model = Serializer.Deserialize<Model>(stream);
Assert.IsNotNull(model.DataFactory);
Assert.IsTrue(model.DataFactory is DataFactory);
答案 0 :(得分:3)
比试图将Spring.NET插入到ProtoBuf对象实例化中更简单的方法是让Spring.NET在构造之后配置对象的依赖关系。 IObjectFactory
接口提供了一种方法IObjectFactory.ConfigureObject(object target, string name)
,旨在实现这一目标。
有关详细信息,请参阅http://springframework.net/doc-latest/reference/html/objects.html#objects-factory-extension
答案 1 :(得分:3)
这基本上是sbohlen之前回答的代码示例。
假设您有以下Spring.Net xml配置文件objects.xml:
<?xml version="1.0" encoding="utf-8"?>
<objects xmlns="http://www.springframework.net">
<object id="IDataFactory" type="Project.Impl.DataFactory, Project" />
<object id="MyModel" type="MyNameSpace.Model, MyAssembly">
<property name="DataFactory" ref="IDataFactory" />
</object>
</objects>
然后你可以这样做:
public void Main(...)
{
var ctx = new XmlApplicationContext("objects.xml");
Model mdl;
using (var file = File.OpenRead("mymodel.bin"))
{
mdl = ProtoBuf.Serializer.Deserialize<Model>(file);
}
ctx.ConfigureObject(mdl, "MyModel");
// mdl.DataFactory will be injected with your idDatafactory instance
}
答案 2 :(得分:1)
这显示了一些可用于拦截反序列化中各个步骤的要点:
using System;
using ProtoBuf;
using ProtoBuf.Meta;
[ProtoContract]
class Foo
{
[ProtoBeforeDeserialization]
private void DoThisBeforeDeserializing()
{
Console.WriteLine("I iz bein deserialized");
}
[ProtoAfterDeserialization]
private void DoThisAfterDeserializing()
{
Console.WriteLine("I haz been deserialized");
}
private static Foo UseThisToMakeInstances()
{
Console.WriteLine("I is being created");
// you could use anything you want here - maybe
// an IOC/DI-based construction
return new Foo();
}
}
public static class Program
{
static void Main()
{
RuntimeTypeModel.Default.Add(typeof (Foo), true)
.SetFactory("UseThisToMakeInstances");
// just using this as a template, so I can use the serializer
var obj = new Foo();
// this does a serialize/deserialize pair
var clone = Serializer.DeepClone(obj);
}
}
(支持类似使用不同的签名,并在上下文中传递等)。通过这三个拦截点(对象创建,反序列化之前,反序列化之后)的组合,在我看来,大多数事情应该是可能的。