2012-09-03 79 views
0

我在我的MVC應用程序中使用Ninject,並試圖實現UnitofWork存儲庫模式。依賴類的構造函數注入

具體而言,我已經定義了一個通用的接口IUnitOfWork,我想然後在構造一些其他(業務邏輯類)以使用該接口的一個實例。這裏是我的控制器的開始......

public class CompanyController : Controller 
{ 
    private readonly IUnitOfWork UnitOfWork; 
    private readonly ICompanyService CompanyDb; 
    private readonly IEmployeeService EmployeeDb; 

    public CompanyController(IUnitOfWork unitOfWork) 
     : base() 
    { 
     this.UnitOfWork = unitOfWork; 
     // This following construction is the problem... 
     this.CompanyDb = new ICompanyService(this.UnitOfWork); 
     this.EmpoloyeeDb = new IEmployeeService(this.UnitOfWork); 
    } 

    // Rest of Controller implementation 
} 

的控制器構造函數工作正常,但我想找到構建各種業務邏輯類的清潔方式,使他們可以在對象的UnitOfWork中引用的資料庫。

的問題是,我不能從接口實例化一個新的業務邏輯的對象,即下面的代碼失敗:

this.CompanyDb = new ICompanyService(this.UnitOfWork); 

由於沒有什麼「線」的ICompanyService接口的具體實現。我想它做的是使用DI(Ninject)創建ICompanyService的實例,其中物理類的構造函數應該是這樣的:

public class CompanyService : ICompanyService { 

    private readonly UnitOfWork db; 

    public CompanyService(IUnitOfWork unitOfWork) { 
     this.db = unitOfWork as UnitOfWork; 
    } 
} 

最終解決 進一步從Joshscorp和Dbaseman的建議(謝謝)我的結構我的代碼如下:

public class CompanyService : ICompanyService { 

    private readonly UnitOfWork db; 

    public CompanyService(IUnitOfWork unitOfWork) { 
     this.db = unitOfWork as UnitOfWork; 
    } 

    // Rest of implementation 
} 


public class CodeFirstController : Controller { 

    private readonly IUnitOfWork UnitOfWork; 
    private readonly ICompanyService CompanyDb; 
    private readonly IEmployeeService EmployeeDb; 


    public CodeFirstController(
     IUnitOfWork unitOfWork, 
     ICompanyService companyDb, 
     IEmployeeService employeeDb 
    ) : base() { 
     this.UnitOfWork = unitOfWork; 
     this.CompanyDb = companyDb; 
     this.EmployeeDb = employeeDb; 
    } 

    // Rest of implementation 
} 

的Ninject模塊如下:

public class CodeFirstModule : NinjectModule { 
    public override void Load() { 
     string connectionString = ConfigurationManager 
      .ConnectionStrings["CompanyConnection"] 
      .ConnectionString; 


     Bind<CodeFirst.DAL.IUnitOfWork>() 
      .To<CodeFirst.DAL.EntityFramework.UnitOfWork>() 
      .InRequestScope() 
      .WithConstructorArgument("connectionString", connectionString); 

     Bind<CodeFirst.DAL.ICompanyService>() 
      .To<CodeFirst.DAL.EntityFramework.CompanyService>() 
      .InRequestScope(); 

     Bind<CodeFirst.DAL.IEmployeeService>() 
      .To<CodeFirst.DAL.EntityFramework.EmployeeService>() 
      .InRequestScope(); 
    } 
} 

的 'InRequestScope()'方法確保在依賴類CompanyService和EmployeeService的構造函數中使用UnitOfWork類的相同實例。

這實現正是我一直在尋找 - 由相關服務類引用的IUnitOfWork對象的單個實例。

+0

我不清楚你想知道什麼。你說你喜歡找到一個乾淨的方式來構建各種類,以便他們可以引用存儲庫?但是,你目前的問題是什麼?請更新您的問題與更多信息(也許更多的代碼)。 – Steven

回答

2

首先,你不能新建一個接口,只有具體的類。

new ICompanyService不會有任何效果。

其次,如果你通常是MVC,我認爲你正在使用的DependencyResolver解決您的對象,這是根據一些反模式。無論您使用什麼解決依賴關係,您都應該始終擁有應用程序的單一入口點,即Global.asax中的每個請求等等以及某種類型的引導程序來加載依賴關係對象圖。

在你的榜樣,我會改變的是構造函數,以在ICompanyServiceIEmployeeService爲好,

public class CompanyController : Controller 
{ 
    private readonly IUnitOfWork unitOfWork; 
    private readonly ICompanyService companyDb; 
    private readonly IEmployeeService rmployeeDb; 

    public CompanyController(IUnitOfWork unitOfWork, 
     ICompanyService companyDb, 
     IEmployeeService employeeDb) 
    { 
     this.unitOfWork = unitOfWork; 
     this.companyDb = companyDb; 
     this.empoloyeeDb = employeeDb; 
    } 

    // Rest of Controller implementation 
} 

這是事業假設你註冊的ICompanyService,並與Ninject或任何IoC的具體實現IEmployeeService (不熟悉Ninject並且不推薦它)

您可能想知道,IUnitOfWork實例如何被注入到ICompanyService具體對象的construc TOR?與注入CompanyController的構造函數的方法相同!

+0

謝謝Joshscorp。我希望在/(所有)依賴類中都使用相同的IUnitOfWork實例,以便數據上下文在所有業務邏輯類中都是同步/共同的。如果我按照您的指示使用構造函數,是不是最終會得到三個單獨的IUnitOfWork對象,每個構造類對應一個對象? – Neilski

+0

@Neilski與Ninject,你可以綁定在特定的範圍內,例如'綁定()。到().InRequestScope()'或'InSingletonScope()'。 – McGarnagle

+0

是的,你可以指定相同的實例注入,因爲dbaseman說 – Joshscorp