2009-02-27 14 views
4

私はコントローラーを正しく作成するために構造マップを取得しようとしていますが、DIを使用してINewsServiceをNewsControllerに挿入しています。ASP.NET MVC、MVCContrib、Structuremap、コントローラファクトリーとして機能していますか?

public class NewsController : Controller 
{ 
    private readonly INewsService newsService; 

    public NewsController(INewsService newsService) 
    { 
     this.newsService = newsService; 
    } 

    public ActionResult List() 
    { 
     var newsArticles = newsService.GetNews(); 
     return View(newsArticles); 
    } 
} 

と私はアプリに

public class Application : HttpApplication 
{ 
    protected void Application_Start() 
    { 
     RegisterIoC(); 
     RegisterViewEngine(ViewEngines.Engines); 
     RegisterRoutes(RouteTable.Routes); 
    } 

    public static void RegisterIoC() 
    { 
     ObjectFactory.Initialize(config => { 
      config.UseDefaultStructureMapConfigFile = false; 
      config.AddRegistry<PersistenceRegistry>(); 
      config.AddRegistry<DomainRegistry>(); 
      config.AddRegistry<ControllerRegistry>(); 
     }); 
     DependencyResolver.InitializeWith(new StructureMapDependencyResolver()); 
     ControllerBuilder.Current.SetControllerFactory(typeof(IoCControllerFactory));    
    } 
} 

を開始するには、このコードを使用しています。しかしのStructureMapはINewsServiceを注入したいとは思われないと、私はエラー このオブジェクトのために定義されていませんパラメータなしのコンストラクタを取得。

私は何が欠けていますか?

答えて

6

各インターフェイスを個別に構成する必要がないように、StructureMapが提供する「既定の規則」メカニズムを使用します。以下は、私がその仕事を作るために使用するコードです:

私のGlobal.asaxのは、(MvcContribからのStructureMapファクトリを使用しています)のApplication_Startでこのラインがあります。

protected void Application_Start() 
{ 
    RegisterRoutes(RouteTable.Routes); 
    ObjectFactory.Initialize(x => 
    { 
     x.AddRegistry(new RepositoryRegistry()); 
    }); 
    ControllerBuilder.Current.SetControllerFactory(typeof(StructureMapControllerFactory)); 
} 

をそしてRepositoryRegistryクラスには、次のようになります。

public class RepositoryRegistry : Registry 
{ 

    public RepositoryRegistry() 
    { 
     Scan(x => 
     { 
      x.Assembly("MyAssemblyName"); 
      x.With<DefaultConventionScanner>(); 
     }); 

    } 

} 

DefaultConventionScannerはISomethingOrOtherとSomethingOrOtherのnameing規則に従い、自動的に元のインターフェースの具体的なタイプとして後者を関連付けるインタフェース/クラスのペアを探します。

あなたはそのデフォルトの大会のメカニズムを使用していなかった場合は、明示的にこの構文を使用して、具体的なタイプのおインターフェースのそれぞれをマッピングするためにレジストリクラスにコードを追加します。

ForRequestedType<ISomethingOrOther>().TheDefaultIsConcreteType<SomethingOrOther>(); 
+0

ありがとうございました!これは私を大いに助け、私は私の問題を回避することができました:) –

+0

@Ervどの名前空間がScanにありますか?私は使用や参照を紛失しているようです。 – ahsteele

+0

私が使用しているバージョン(8ヶ月が経過していますが、最近変更されたものは見ていません)では、スキャンはRepositoryRegistryが継承しているレジストリベースクラスのメソッドです。 –

0

私が何かを紛失していない限り、あなたはINewsServiceにどのような具体的なタイプを使用するかをStructureMapに伝えていません。あなたのような何かを追加する必要があります。

TheConcreteTypeOf<INewsService>.Is<MyConcreteNewsService>(); 

私は私の頭の上から正確な構文を知らないが、それはあなたが欠けているものです。これを指定すると、コントローラに注入するINewsServiceのインスタンスがわかります。

+0

私はINewsServiceなどのレジストリにすべての正しいマッピングを追加していますので、問題の原因になってはいけません。 –

+0

私はあなたがそれをインスタンス化しているコードを見ていません。 – Micah

+0

レジストリにコードを表示できますか? – Micah

0

ASP。 NET MVCは現在、デフォルトのパラメータレスコンストラクタを使用してコントローラをインスタンス化します。これにより、コンストラクタベースの依存性注入が排除されます。これを行うには、実際にはドキュメントが存在しないにもかかわらず、StructMap(とCastle/Spring.NET/Unity)のサポートが組み込まれているMvcContribプロジェクトを使用する必要があります(文字通り、良いサインではない)。このスレッドのErv Walterのコードサンプルは、StructureMapの統合をセットアップする方法を示しています。

関連する問題