私はNinject経由で依存関係注入を使用するプロジェクトに取り組んでいます。これまでは非常にうまくいっていて、私はDIをたくさん好んでいましたが、今はいくつかのオブジェクトを直列化する必要があると判断し、DIパターンに従うのが難しいと感じています。工場で作成したオブジェクトをシリアライズする方法
が、私はこのように、バーのリストを持っており、工場を介してそれらを作るのFooというクラスを、持っていると言う:
public class Foo
{
private List<Bar> _bars;
private BarFactory _barFactory;
...
public void MakeBar()
{
_bars.Add(_barFactory.MakeBar());
}
}
ここ_barFactory.MakeBar()
が呼び出されたときに行われますバーは、です。私はバーをシリアル化したい:
public class Bar : ISerializable
{
private List<IPickle> _pickles;
private PickleFactory _pickleFactory;
public Bar(PickleFactory factory)
{
_pickleFactory = factory;
}
public void MakePickle(int x)
{
_pickles.Add(_pickleFactory.MakePickle(x));
}
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
//serialize member variables here
}
//Constructor called during deserialization
private Bar(SerializationInfo info, StreamingContext context)
{
//fill in member variables with data from SerializationInfo
}
}
Barは独自の工場とピクルスのコレクションを持っていることに注意してください。ここに問題があります:Barの逆シリアル化コンストラクタが呼び出されると、別のPickleFactoryを取得する方法がありません。元のPickleFactoryはBarFactoryによってBarに渡されましたが、逆シリアル化コンストラクタはBarFactoryによって呼び出されませんでした。
この問題を解決する私の現在の計画は、Barのすべてのシリアライズ可能なメンバーをBarDataObjectという独自のクラスに抽出することです。それからBarDataObjectを直列化可能にしますが、Bar自体は作成しません。 BarDataObjectをパラメータとして受け取り、BarDataObjectのすべての情報を埋め込んだBarを構築するBarFactoryに関数を追加します。
しかし、Pickle でもには、それを作成した工場から入手したサービスクラスがあり、それもシリアル化できません。だから、PickleからDataObjectを抽出する必要があり、BarDataObjectはPickleDataObjectを保持する必要があります。また、Pickleにもデータとサービスが混在するメンバー変数があるとしますか?私はそのためにもDataObjectを作成し維持する必要があります。私のプロジェクトには、シリアル化する必要がある他の多くのものがあり、おそらく同じ問題に直面するだろうと考えると、これは本当に酷いようです。
もっと良い解決策がありますか?私は何か間違っているのですか?DI賢明ですか?私はDIとNinjectで作業を始めましたが、サービスクラスを注入されたオブジェクトを直列化する良い方法を思いつく人はいません。
シリアル化情報を受け取る 'BarFactory'クラスにコンストラクタを追加できますか? – Matthew
Fooはどのような種類のオブジェクトですか?それは「新鮮な」か「注射可能な」か? (http://misko.hevery.com/2008/09/30/to-new-or-not-to-new/)。 –
@Matthew - 私が行った場合、SerializationInfoはどのように工場に持ち込まれますか? Barのプライベートコンストラクタが呼び出された時点で、既にBarコンストラクタに入っているので、Barを作るように工場に依頼するのは時期尚早です。BarはBarFactoryについて知らないでしょう。 – tandersen