Spring.net и protobuf: создание объектов - PullRequest
2 голосов
/ 11 февраля 2012

В настоящее время в нашем приложении используется protobuf-net, и я хотел бы добавить свойства после десериализации.

например, если объект сериализации имеет свойство с именем 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 для создания объекта и затем устанавливал свойства. Как вы думаете, я мог бы сделать это?

Спасибо!

Идеальный сценарий

Я бы хотел, чтобы DataFactory был установлен непосредственно Spring.net после десериализации protobuf.

Model model = Serializer.Deserialize<Model>(stream);
Assert.IsNotNull(model.DataFactory);
Assert.IsTrue(model.DataFactory is DataFactory);

Ответы [ 3 ]

3 голосов
/ 12 февраля 2012

Это в основном пример кода для ответа 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
}
3 голосов
/ 11 февраля 2012

Более простой подход, чем попытка вставить 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 голос
/ 13 февраля 2012

Здесь показаны некоторые точки, которые вы можете использовать для перехвата различных этапов десериализации:

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

(есть поддержка для подобных с использованием разных подписей, передачи в контексте и т. Д.)Сочетание этих трех точек перехвата (создание объекта, до десериализации, после десериализации) кажется мне, что большинство вещей должно быть возможным.

...