2013-10-12 16 views
4

我在this post上閱讀他們正在使用依賴注入在每個mvc請求上加載存儲庫實例。使用DI在每個mvc請求上加載存儲庫實例

我不確定如果我理解正確,但我目前在我的mvc應用程序中使用。其中實現IUserRepository接口的UserRepository。此接口的控制器構造

public class UserController : Controller 
{ 
    private IUserRepository repository; 
    public UserController(IUserRepository rep) 
    { repository = rep; } 

    public UserController() : this(new UserRepository()) {} 
} 

注入,但使用這個接口(IUserRepository)我看不出有什麼好處,我可以用UserRepository沒有接口。顯然,有人認爲有人認爲這是正確的方法(我已經在apress mvc4 book上找到了它),我會懇請某人詳細說明爲什麼這是更好的方法,而不是使用沒有接口的存儲庫。

考慮到這一點我想請人共享具體事例或就如何實現此方法鏈接(使用依賴注入,在每個MVC要求加載庫實例)。

回答

5

DI背後的主要思想是強制您看到大圖而不是具體實現。

您的控制器需要獲取用戶,但不應該關心具體的實現(您的存儲庫是否從數據庫,Web服務,xml文件等中獲取用戶,還是使用Linq2Sql,EntityFramework,Dapper或引擎蓋下的其他東西)。

您的控制器依賴於可以在構造函數,屬性或方法中注入的那段代碼,但它並不真正關心具體的實現。

DI消除了控制器和存儲庫之間的緊密耦合,允許您通過模擬存儲庫編寫單元測試,並且可以輕鬆更改存儲庫的具體實現(例如,使用PetaPoco而不是EntityFramework),而無需觸摸其他的代碼。

您還應該看看SOLID原則:http://en.wikipedia.org/wiki/SOLID_(object-oriented_design)

2

接口的主要優點是他們鼓勵抽象。如果你想模擬一個完全不同的實現(例如,執行單元測試時,你應該這樣做:),你只需要將IUserRepository的另一個實現注入到UserController構造函數中。這就是我的看法,它是使用接口的主要優點之一。

4

當我的團隊開始使用依賴注入時,我們正在閱讀Steven Sanderson的一本好書「Pro ASP.NET MVC 2 Framework」。在本書中,他描述瞭如何使用流行的依賴注入框架Castle Windsor。在另一本書「Pro ASP.NET MVC 3框架」中,據我所知,如何使用Ninject(另一個框架)進行了描述。

爲了使用溫莎城堡:

首先,你必須寫控制器工廠的定製實現:

/// <summary> 
/// Controller factory the class is to be used to eliminate hard-coded dependencies 
/// between controllers and other components 
/// </summary> 
public class ControllerFactory : DefaultControllerFactory 
{ 
    private readonly IWindsorContainer container; 

    public WindsorControllerFactory(IWindsorContainer container) 
    { 
     this.container = container; 
    } 

    public override void ReleaseController(IController controller) 
    { 
     container.Release(controller.GetType()); 
    } 

    protected override IController GetControllerInstance(System.Web.Routing.RequestContext requestContext, Type controllerType) 
    { 
     return (IController)container.Resolve(controllerType); 
    } 
} 

然後,你必須寫入所有控制器的安裝程序。

/// <summary> 
/// Castle windsor installer for controller components. 
/// </summary> 
public class ControllersInstaller : IWindsorInstaller 
{ 
    /// <summary> 
    /// Performs the installation in the <see cref="T:Castle.Windsor.IWindsorContainer"/>. 
    /// </summary> 
    /// <param name="container">The container.</param> 
    /// <param name="store">The configuration store.</param> 
    public void Install(IWindsorContainer container, IConfigurationStore store) 
    { 
     container.Register(
      Classes.FromThisAssembly() 
       .BasedOn<IController>() 
       .LifestyleTransient() 
     ); 
    } 
} 

如果你想與依賴你也應該寫一個安裝程序爲他們的倉庫來解決。它將類似於ControllersInstaller,但生活方式將是LifestylePerWebRequest()。 PerRequestLifestyle應該在web.config文件中註冊。

<httpModules> 
    <add name="PerRequestLifestyle" type="Castle.MicroKernel.Lifestyle.PerWebRequestLifestyleModule, Castle.Windsor" /> 
</httpModules> 

然後,你必須創建容器的一個實例時,應用程序啓動在Global.asax.cs中:

public class MvcApplication : System.Web.HttpApplication 
{ 
    private static IWindsorContainer container; 

    protected void Application_Start() 
    { 
     container = new WindsorContainer(); 
     container.Install(FromAssembly.This()); 

     //Set the controller builder to use our custom controller factory 
     var controllerFactory = new WindsorControllerFactory(container); 
     ControllerBuilder.Current.SetControllerFactory(controllerFactory); 
    } 

    protected void Application_End() 
    { 
     container.Dispose(); 
    } 
} 

還有一個link到溫莎城堡的文檔,你可以找到更多信息與lifestylesASP.NET MVC 3 application tutorial一起工作。

**當您使用接口

  1. 更容易在你的代碼(有些嘲諷的框架有限制)
  2. 更容易開發新的實施和測試它沒有在舊的變化模擬依賴。

**如果您已實施並設置了控制器工廠,則不需要控制器中的默認構造函數。

相關問題