C# 为什么GenericRepository在我使用依赖注入接口时返回一个类?

C# 为什么GenericRepository在我使用依赖注入接口时返回一个类?,c#,entity-framework,dependency-injection,ninject,unit-of-work,C#,Entity Framework,Dependency Injection,Ninject,Unit Of Work,我正在用C、.NETFramework 4.5、EntityFramework 6.1.0代码优先和Ninject开发一个ASP.NETMVC5WebAPI 为了做到这一点,我使用了通用存储库、工作单元和依赖项注入模式,至少,我正在尝试遵循它们 我有以下项目: MyProduct.Domain MyProduct.Interface MyProduct.WebAPI 在MyProduct.Interfaces上,我有两个接口: IGenericRepository 工夫 在MyProduct.D

我正在用C、.NETFramework 4.5、EntityFramework 6.1.0代码优先和Ninject开发一个ASP.NETMVC5WebAPI

为了做到这一点,我使用了通用存储库、工作单元和依赖项注入模式,至少,我正在尝试遵循它们

我有以下项目:

MyProduct.Domain

MyProduct.Interface

MyProduct.WebAPI

在MyProduct.Interfaces上,我有两个接口:

IGenericRepository 工夫 在MyProduct.Domain上,我有三个文件夹:

类的具体化:EFDbContext、GenericRepository 实现IGenericRepository和UnitOfWork实现 我的工作。 EF代码优先配置的配置。 具有表示数据库表的类的实体。 这是我的IUnitOfWork界面:

public interface IUnitOfWork
{
    void SaveChanges();
    IRepository CustomerRepository { get; }
    IRepository ProductRepository { get; }
    IRepository OrderRepository { get; }
}
以及具有构造函数注入的控制器:

private IUnitOfWork unitOfWork;

public OrderController(IUnitOfWork unitOfWork )
{
    this.unitOfWork = unitOfWork;
}
现在我的问题是:

如果我使用UnitOfWork.CustomerRepository.GetAll;获取所有客户

这将返回在MyProduct.Domain中定义的IEnumerable及其客户。对吗

我试图解耦MyProduct.WebApi上的任何实体框架引用,但如果我必须添加对MyProduct.Domain、文件夹实体中定义的客户的引用,我不会解耦任何东西,因为我引用的是MyProduct.Domain项目

也许我还没有理解这里的任何内容,因为我不明白为什么我要使用IUnitOfWork接口,然后在我的控制器的任何操作上,我有一个来自MyProducts.Domain的类的实例


我是否需要将实体移动到另一个名为MyProduct.Model的项目中?

这是您必须做出的选择,将所有实体移动到另一个项目中并不重要。但就我而言,我总是这样做

如果您有疑问,这里有一个如何实现GenericRepository的想法
出于多种原因,在应用程序中使用工作单元和存储库绝对是个好主意。然而,这并不意味着您必须创建自己的工作单元和存储库

实体框架的DbContext已经是一个工作单元,并且包含的DbSet已经是通用存储库。因此,除了使用EF,什么都不做已经满足了良好的实践

许多人会指向单元测试的存储库,而且绝对是这样。但是,从EF6开始,您现在可以为单元测试正确模拟EF上下文。如果你绝对想把它抽象出来,那就使用一个具体的存储库

创建自己的UnitOfWork类的唯一原因是以下两个原因之一。1您打算更换您的数据库技术。或者2您使用的数据库技术没有实现UnitOfWork ie ADO.NET或其他任何功能

就我而言

大多数人认为他们可能会取代他们的数据库技术,但这几乎从未发生过。如果你这么做了,很可能你已经让太多的实现细节泄露到了你的设计中,这无论如何都不是一件容易的事情

对于至少95%使用自定义通用UnitOfWork/Repositories的用户来说,这只是无用的额外工作。对于获得收益的5%,可能有更好的方法来实现相同的收益

至于2


如果您没有使用已经实现UnitOfWork的ORM或其他技术,那么您肯定应该自己实现一个。

DbContext已经是UnitOfWork,但使用另一个UnitOfWork作为接口或类,它仅用于添加IRepository属性。如果你不想使用它,实际上我在控制器中使用了我自己的UnitOfWork、DbContext和invidual iRepositions的组合,你必须评估每种情况并选择最佳选项。谢谢你的回答,我的问题的答案是什么?我需要把我的嫉妒转移到另一个项目吗?我之所以使用这种方法,是因为我想使用TDD和mocking,我想将解决方案中的所有内容解耦。@VansFannel-请重新阅读我的第三段。您可以在不创建通用存储库或uow的情况下测试和模拟EF 6,而具体的存储库也是可测试的。你可以不用额外的工作就完成所有这些工作是的,但我不是问我是否必须使用自己的UnitOfWork实现。@VansFannel-你说我可能什么都不懂,因为我不明白为什么要使用IUnitOfWork,我的意思是,如果你不明白为什么要这样做。。你可能不需要这样。对不起,你的回答没有回答我的问题。我的问题是:我是否需要将我的实体移动到另一个名为MyProduct.Model的项目中?您的工作单元应该包装对存储库的调用。这就是重点。UoW的意义在于,当您有多个存储库需要共享一个上下文时@mijal发布了一个很好的链接,解释了为什么你想使用它。如果您的用例不匹配,那么您没有理由不能直接使用存储库。