我在我的MVC应用程序中使用Ninject,并且正在尝试实现Unit of Work存储库模式。
具体来说,我已经定义了一个通用的IUnitOfWork接口,然后我想在构造函数中为其他一些(Business Logic类)使用这个接口的实例。这是我的控制器的开始......
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
}
Controller构造函数正常工作,但我想找到一种构建各种Business Logic类的简洁方法,以便它们可以引用UnitOfWork对象中的存储库。
问题是我无法从界面实例化新的Business Logic对象,即以下代码失败:
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();
}
}
IUnitOfWork绑定上的'InRequestScope()'方法确保在依赖类CompanyService和EmployeeService的构造函数中使用UnitOfWork类的相同实例。
这实现了我正在寻找的东西 - 依赖服务类引用的IUnitOfWork对象的单个实例。
答案 0 :(得分:2)
首先,你不能新建一个接口,只能打造具体的类。
new ICompanyService
永远不会奏效。
其次,如果你通常是MVC,我认为你正在使用DependencyResolver来解析你的对象,这是一种反模式。无论您使用什么来解决依赖关系,您都应该始终只有一个应用程序入口点,即Global.asax等中的每个请求......以及某种类型的引导程序来加载依赖项对象图。
在您的示例中,我将更改的是构造函数,同时接收ICompanyService
和IEmployeeService
,
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
和IEmployeeService
与Ninject或任何IoC容器的具体实现(不熟悉Ninject并且不推荐它)
您可能想知道,IUnitOfWork
实例如何被注入到ICompanyService
具体对象的构造函数中?它被注入CompanyController
的构造函数的方式相同!