1

私は現在作業中です。コントローラを作成し、自動的にElmah ErrorHandlerを設定するカスタムControllerFactoryクラスがあります。StructureMapを使用してコントローラにリポジトリクラスを注入する方法は?

public class BaseControllerFactory : DefaultControllerFactory 
{ 
    public override IController CreateController(RequestContext requestContext, string controllerName) { 
     var controller = base.CreateController(requestContext, controllerName); 
     var c = controller as Controller; 
     if (c != null) { 
      c.ActionInvoker = new ErrorHandlingActionInvoker(new HandleErrorWithElmahAttribute()); 
     } 
     return controller; 
    } 

    protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType) { 
     try { 
      if ((requestContext == null) || (controllerType == null)) 
       return base.GetControllerInstance(requestContext, controllerType); 

      return (Controller)ObjectFactory.GetInstance(controllerType); 
     } 
     catch (StructureMapException) { 
      System.Diagnostics.Debug.WriteLine(ObjectFactory.WhatDoIHave()); 
      throw new Exception(ObjectFactory.WhatDoIHave()); 
     } 
    } 
} 

私は自分のコントローラにいくつかのコードを挿入するためにStructureMapを使いたいと思っています。たとえば、リポジトリクラスを自動的に挿入したいと思います。どのようにすべきである私は、その後のStructureMap

ObjectFactory.Initialize(x => { 
    x.For<IContactRepository>().Use<MyContactRepository>(); 
}); 

をタイプを登録している

は、私はすでに私のリポジトリのクラスを作成しているとも私は

public FirmController(IContactRepository contactRepository) { 
    _contactRepository = contactRepository; 
} 

リポジトリクラスを受けるコントローラにコンストラクタを追加しました私はFirmControllerに注入された具体的なクラスIContactRepositoryを持つようにCreateControllerメソッドのコードを変更しますか?

EDIT

私はのStructureMapを使用するようにBaseControllerFactoryを変更しました。しかし、私はラインで例外を得る

return (Controller)ObjectFactory.GetInstance(controllerType); 

すべてのヒント?

+1

あなたは何を得ていますか?カスタムコントローラファクトリを設定する前に、app_startでInitializeコードを呼び出していますか? I. StaticClass.InitializeStructureMap();次に、ControllerBuilder.Current.SetControllerFactory(新しいBaseControllerFactory()); – Paul

+0

良いキャッチ。私は、カスタムコントローラファクトリを設定した後、初期化コードを呼び出していました。 – Lorenzo

答えて

5

液に入力する前に、私はこれを実現する最良の方法は、のStructureMapの枠組みの中でレジストリクラスからサブクラス化するクラスを持っているだろうというのObjectFactory

よりも、SMを初期化するコンテナタイプを使用することをお勧めします。したがって、私のレジストリは、

public class MyAppRegistry : Registry 
{ 
    public MyAppRegistry() 
    { 
     For<IContactRepository>().Use<MyContactRepository>(); 
    } 
} 

のようになります。そして、設定中にこのレジストリを使用するようにSMに指示してください。

var container = new Container(x=>x.AddRegistry(new MyAppRegistry()); 

これは、Global.asaxのApplication_Startから実行されます。上記の行の後、BaseControllerFactoryを使うようにmvcのControllerBuilderを設定します。今SMはすべての依存関係を解決できるはずです

+0

あなたの答えをありがとう。コンテナと 'ObjectFactory.Initialize'メソッドの使用に違いはありますか?私は少しコードを変更して、私は実際には内部のAddRecistryでInitializeメソッドを使用しています。 – Lorenzo

+0

申し訳ありません、私は 'AddRegistry()'を意味しました – Lorenzo

+0

あなたは歓迎Lorenzo! ObjectFactoryは、コンテナの周りの静的ラッパーです。したがって、Initializeを呼び出すと、初期化式で渡されたContainerのctorが呼び出されます。もう一つ注意しなければならないことは、InitializeがObjectFactoryで再び呼び出された場合、以前のすべての登録を消去するということです。したがって、コンテナを使用すると、初期設定の後に設定を呼び出すことができるだけでなく、既存の登録に追加できるようになります。あなたのプロジェクトに幸運を祈る! – Hakeem

関連する問題