2009-11-10 51 views
0

我是相當新的StructureMap,但我的理解是,有來自ObjectFactory得到一個實例的方法有兩種:使用StructureMap將相同接口的不同實現注入控制器的最佳方式是什麼?

  1. 由式(即ObjectFactory.GetInstance<IFoo>()
  2. 按類型和名稱(即ObjectFactory.GetNamedInstance<IFoo>("foo.bar")

我已經看到了很多示例,演示瞭如何創建一個MVC控制器工廠,該工廠將使用StructureMap提供控制器實例,並且在大多數情況下,我已經看到他們正在使用上述選項#1中的方法。

比方說,我們有一些控制器,它接受一個庫/ DAO接口作爲構造參數...

public class FooController : Controller 
{ 
    public FooController (IFooRepository fooRepository) 
    { 
    // constructor code goes here 
    } 
} 

使用接口類爲我提供了對「注入」該接口的任何實現的能力我的控制器。如果對於兩種不同的操作,我想注入不同的實現?也許在一種情況下,我需要實現一個將查詢SQL Server數據庫的存儲庫,而在另一種情況下,我需要一個將從XML文件或通過Web Service調用獲取數據的實現。

看來,如果您使用ObjectFactory.GetInstance()方法,那麼您將被限制爲僅向控制器提供存儲庫接口的單個​​實現。

但是,如果使用命名實例,那麼最終必須根據MVC框架提供的控制器的名稱創建實例。在大多數情況下,這通常是來自URL的控制器名稱,但實際上取決於路由配置。這看起來似乎很混亂,隨着路線數量的增加,只會變得更加混亂。

是否有任何替代方法可以允許不使用命名實例的不同控制器實例化策略?建立單獨的控制器,並確保任何給定控制器中的所有操作對於同一個存儲庫/ DAO類的具體實例都是有效的,是否更好?

回答

0

對於什麼是值得的,我結束了與命名實例,其中每個實例的名稱是基於MVC框架從URL中取出的控制器的名稱。

例如,URL /foo/DoSomething可能會從ObjectFactory獲取一個IController實例,該實例使用一個使用SqlClient API進行數據訪問的Repository對象實例化。然後URL(如/foo.webservice/DoSomething)將創建同一個具體控制器類的實例,但將該實例的構造器傳遞給使用Web服務進行數據訪問的存儲庫對象。

有幾種方法可以爲構造函數參數覆蓋StructureMap的默認自動佈線行爲。在我的情況下,我使用了CtorDependencyIs方法,並且映射看起來像這樣...

// create a named instance for the "foo" controller that uses the SqlClient based repository 
InstanceOf<IController>() 
    .Is.OfConcreteType<FooController>() 
    .CtorDependency<IFooRepository>() 
    .Is(new FooRepositorySql(Constants.FooConnectionString)) 
    .WithName("foo"); 

// create a named instance for the "foo.webservice" controller that uses the Web Service based repository 
InstanceOf<IController>() 
    .Is.OfConcreteType<FooController>() 
    .CtorDependency<IFooRepository>() 
    .Is(new FooRepositoryWs(Constants.FooServiceUrl)) 
    .WithName("foo.webservice"); 
相關問題