Spring.net和protobuf:对象实例化

时间:2012-02-10 22:01:13

标签: protobuf-net spring.net

我们目前在我们的应用程序中使用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);

3 个答案:

答案 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);
    }
}

(支持类似使用不同的签名,并在上下文中传递等)。通过这三个拦截点(对象创建,反序列化之前,反序列化之后)的组合,在我看来,大多数事情应该是可能的。