0

HTTPSessionにデータを保存するクラス「DataSaver」が必要です。しかし、考えを変えて、ファクトリ クラスにオブジェクトを作成させ、代わりにファイルまたはデータベースに保存する機能も必要です。

次のような DataSaver オブジェクトを作成できるようにしたいと考えています。

IDataSaver obj = DataSaverFact.Create();

しかし、明らかに、データ ソースはインスタンス化されるものに応じて異なるリソースを必要とします (つまり、セッションに保存するクラスには現在の HTTPSession が必要であり、データベース バージョンには接続文字列が必要になるなど...)。

しかし、作成メソッドに何も渡す必要はありません。

それは可能ですか?

次のようなファクトリ クラスで依存性注入を使用することを考えていました。

public interface IDataSaverFact
{
    IDataSaver Create();
}

public interface IDataSaver
{
    public void Save(Object data);
}

public SessionSaver : IDataSaver
{
    //PARAMETER REQUIRED SINCE SESSION ONLY AVAILABLE FROM CALLER DURING WEB REQUEST
    public SessionSaver(HTTPSession session)
    {
    }

    public void Save(Object data) {....}
}


public FileSaver : IDataSaver
{
    //NO PARAMETER HERE. THIS WILL JUST SAVE TO A FILE FROM CONFIG
    public FileSaver ()
    {
    }

    public void Save(Object data) {....}
}

public DataSaverFact : IDataSaverFact
{
    public IDataSaver Create()
    {
        * IS IT POSSIBLE/APPROPRIATE TO HOOK THIS UP VIA A DI FRAMEWORK? *
        return new SessionSaver(session);
    }
}

私はいくつかの例を見てきました。ここでは Is there a pattern for initializing objects created via a DI containerのように、リンクされた例が作成時にパラメーターを渡していることを除いて、上記のものに近いようです。

ファクトリへの呼び出しによって作成が変わることは望ましくありませんが、技術的な理由でデータ ソースを変更する場合は、コンパイル時に DataSaver を変更できる機能が必要です。

そして、ファクトリークラスを次のように変更します

public DataSaverFact : IDataSaverFact
{
    public IDataSaver Create()
    {
        return new FileSaver();
    }
}

*編集、これはMVC3プロジェクトで使用されます

4

1 に答える 1

2

インターフェイスが定義されていて、具体的なオブジェクトの型がコンパイル時に定義されている場合、DI が必要な理由がまったくわかりません。ファクトリが作成するオブジェクトを決定するために使用する値を含む構成ファイルを持つことができます。

例えば

public DataSaverFact : IDataSaverFact
{
    public IDataSaver Create()
    {
      if config setting = "FileSaver" then
        return new FileSaver();
      else
        return new SessionSaver();
    }
}

ハードコーディングされた IF ステートメントを回避したい場合は、型定義を構成ファイルに保存してから、Activator.CreateInstance を使用して戻りオブジェクトをインスタンス化できます。

于 2012-12-07T00:52:44.327 に答える