3

私は構造体マップを使用していて、コントローラのプロパティにインスタンス(コンテナで構築)を挿入したいとします。インスタンスは、httpセッションコンテキストコンテナに名前を付けて格納する必要があります。 自分のアプリケーションの以前のバージョンでは、私は、カスタムのDIフレームワークを使用しました、そのようなものを作るのに十分な簡単だった:構造体マップで指定されたセッションインスタンス戦略を使用したセッターの修復

public class MyController : Controller 
{ 
    [InjectSession("MySessionInstanceKey")] 
    public MyManager Manager {get; set;} 
} 

はのStructureMapでそれを行うには任意の簡単な方法はありますか?
または、私は自分のカスタム属性と注入ロジックをSMフレームワークに導入することができます(何とかフレームワークを拡張します)?
これを解決する方法を見つけてもらい、ありがとうございます。

P.S.私は一時的な解決策を見つけたが、それはのIoCフレームワークとコントローラの結束を高め、多くのコードが含まれています

private const string ordersBulkManagerKey = "_OrdersBulkManager"; 
public BulkManager OrdersBulkManager 
{ 
    get 
    { 
     var manager = Session[ordersBulkManagerKey] as BulkManager; 
     if(manager == null) 
     Session[ordersBulkManagerKey] = manager 
      = ObjectFactory.GetInstance<BulkManager>(); 
     return manager; 
    } 
} 

だから、私はそこにObjectFactory.GetInstanceを使用したくない...

答えて

2

コンフィグレーションされたASP.NET MVCとStructureMapを結びつける方法についてのいくつかのブログ記事があります。 (次のコードのほとんどは、さまざまな投稿の要約です)

これを行う一般的な方法は、独自のコントローラファクトリクラスを宣言することです。これにより、コンストラクタを介して依存関係を挿入できます。 (ASP.NET MVCが使用するデフォルトのコントローラファクトリでは、デフォルトのコンストラクタが必要です)

MyControllerクラスでは、MyManagerパラメータを受け入れるコンストラクタを使用しますコントローラファクトリクラス)

public class MyController : Controller 
{ 
    private readonly ISomeService _someService; 
    //Constructor Injection. 
    public MyController(ISomeService someService){ 
     _someService = someService; 
    } 
} 

次あなたはASP.NET MVCを構成しますが)私たちはStructureMapControllerFactoryを呼ぶであろう(この新しいコントローラーファクトリクラスを使用して行います。 StructureMapControllerFactoryで

protected void Application_Start() 
{ 

    //This is where you register your concrete types with StructureMap 
    Bootstrapper.ConfigureStructureMap(); 

    //Our very own Controller Factory 
    ControllerBuilder.Current.SetControllerFactory 
    (new StructureMapControllerFactory()); 

    RegisterRoutes(RouteTable.Routes); 
} 

、私たちは私たち(私たちはすべての私達の依存関係を有線している提供)コントローラを返すあなたにObjectFactory.GetInstanceを呼び出す

public class StructureMapControllerFactory : DefaultControllerFactory 
{ 
    protected override IController GetControllerInstance(Type controllerType) 
    { 
     if (controllerType == null) return null; 
     try 
     { 
      return ObjectFactory.GetInstance(controllerType) as Controller; 
     } 
     catch (StructureMapException) 
     { 
      System.Diagnostics.Debug.WriteLine(ObjectFactory.WhatDoIHave()); 
      throw; 
     } 
    } 
} 

うまくいけば、私の説明は明らかですが、あれば私に知らせてそれではなく、私はそれを拡張することができます。

ところで、以下のスニペットは、ブートストラップコードの例です。

public static class Bootstrapper 
{ 
    public static void ConfigureStructureMap() 
    { 
     ObjectFactory.Initialize(
     x => x.AddRegistry(new MyApplicationRegistry()));    
    } 
} 

public class MyApplicationRegistry : Registry 
{ 
    public MyApplicationRegistry() 
    { 
     ForRequestedType<ISomeService>() 
     .CacheBy(InstanceScope.Your_Choice_Here) 
     .TheDefault.Is.OfConcreteType<SomeService>(); 
    } 
} 

注:さまざまなInstanceScopeオプションについては、StructureMapのドキュメントを参照してください。あなたが自分でそれを

For<IBulkManager>() 
    .LifecycleIs(Lifecycles.GetLifecycle(InstanceScope.HttpSession)) 
    .Use<BulkManager>(); 

を実装する必要はありませんので

+0

おかげで男に変わるでしょう、あなたのオブジェクトのライフサイクルを制御することができます!コンストラクタ注入+ライフサイクル管理=これは私が必要なものです – IlliakaillI

2

のStructureMapは、だからあなたのコードが

public IBulkManager OrdersBulkManager 
{ 
    get { return ObjectFactory.GetInstance<IBulkManager>(); } 
} 
+0

ありがとうジョン、それは私のコントローラからロジックのライフサイクルとスコープの部分が消えてしまったようです。 ObjectFactoryへの参照はまだありますが、実際には気にしません。約8ヶ月前です。haha 他のコードとDIコンテナを結ぶのは良いスタイルではないかもしれませんが、属性注入の私の例は同じ悪いスタイルです。 だから、私はおそらくあなたのオブジェクトは常にそれらを必要としないので、BulkManagerをあなたのコントローラとして動作させるサービスにするのが理にかなっていることがあるかもしれない、プロパティーセッターとコンストラクタインジェクション技術 – IlliakaillI

+0

のライフサイクル定義を使うべきですあなたのコントローラのこのプロパティを持たないように(のクライアント)。 –

関連する問題