2012-09-03 72 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