1

次のような StructureMap 構成があります。

cfg.For<ICacheOrder>().Use<CacheOrder>().Ctor<int>().Is(context => LoginHelper.LoginID);
cfg.For<ICacheProduct>().Use<CacheProduct>().Ctor<int>().Is(context => LoginHelper.LoginID);
cfg.For<ISQLOrder>().Use<SQLOrder>().Ctor<int>().Is(context => LoginHelper.LoginID);
cfg.For<ISQLProduct>().Use<SQLProduct>().Ctor<int>().Is(context => LoginHelper.LoginID);

コンストラクター インジェクションを介して、作成時に決定される int LoginID を必要とするオブジェクトのチェーンを作成できます。静的 LoginHelper が LoginID を決定します。

現在、私の設定では、作成されたすべてのオブジェクトに対して LoginHelper が呼び出されます。おそらく StructureMap の IContext を介して、LoginID を「記憶」し、一連の作成の中で一度だけ決定する方法はありますか?

StructureMap が構築してキャッシュできる ILogin インターフェイス/コンクリートをリファクタリングして作成できることはわかっていますが、さまざまなレイヤーが単純な int LoginID のみに関係することをお勧めします。

4

1 に答える 1

3

サービスにプリミティブ構成値を挿入することは問題ありませんが、同じプリミティブを複数のサービスに繰り返し挿入すると、抽象化が失われます。

これは明らかに構成に当てはまります。抽象化がありません。

解決策は、これらのサービスをプリミティブ値ではなく抽象化に依存させることです。例えば:

public interface ICurrentUser
{
    int LoginID { get; }
}

また、次のようにかなり単純な実装を作成できます。

public class CurrentUserImpl : ICurrentUser
{
    public CurrentUserImpl()
    {
        this.LoginID = LoginHelper.LoginID;
    }

    public int LoginID { get; private set; }
}

CacheOrderこれは、 、CacheProductSQLOrderおよびのコンストラクターを変更する必要があることを意味しますが、SQLProductこれを行うと、構成がより保守しやすくなります。

cfg.For<ICacheOrder>().Use<CacheOrder>();
cfg.For<ICacheProduct>().Use<CacheProduct>();
cfg.For<ISQLOrder>().Use<SQLOrder>();
cfg.For<ISQLProduct>().Use<SQLProduct>();

次のように登録できるようになったため、「パラメーター リテラルを記憶する」という問題はすぐに解消さICurrentUserれます。

cfg.For<ICurrentUser>().Use<CurrentUserImpl>();

Structure Map のデフォルトのライフサイクルはリクエストごと (オブジェクト グラフごと) であるため、同じインスタンスが単一のオブジェクト グラフ内のすべてのオブジェクトに注入されます。

別のオプションは、HttpContextライフサイクルを使用して登録することですが、これはもちろん、ASP.NET Web アプリケーションを実行している場合にのみ機能します。

于 2013-05-21T11:30:25.920 に答える