我正在尝试使用ASP.NET / Entity Framework Core实现基本的UoW / Repository模式,我遇到了非常令人不安的行为。
我的解决方案共包含4个项目。
.DAL项目,其中定义了我的实体类,并定义了我的DbContext:
public class Product
{
public int Id { get; set; }
public string Name { get; set; }
}
public class ApplicationDbContext : DbContext
{
public DbSet<Product> Products { get; set; }
}
.Facade 项目,其中定义了IUnitOfWork和IProductRepository:
public interface IUnitOfWork
{
IProductRepository Products { get; }
}
public interface IProductRepository
{
string GetName(int id);
}
.Facade.EF 项目,我的Facade是用EF实现的:
public class UnitOfWork : IUnitOfWork
{
private ApplicationDbContext _context;
public IProductRepository Products { get; private set; }
internal ApplicationDbContext Context { get { return _context; } }
public UnitOfWork()
{
_context = new ApplicationDbContext();
Products = new ProductRepository(this);
}
}
public class ProductRepository : IProductRepository
{
private ApplicationDbContext _context;
public ProductRepository(UnitOfWork uow)
{
_context = uow.Context;
}
public string GetName(int id)
{
return _context.Products
.Where(x => x.Id == id)
.Select(x => x.Name)
.FirstOrDefault();
}
}
.DemoApp 项目应该是我的应用程序代码。这个项目应该只知道UnitOfWork和UserRepository,而不是ApplicationDbContext类。
.DAL引用实体框架6.1.3。
.Facade没有引用任何内容。
.Facade.EF引用.DAL项目,.Facade项目和实体框架6.1.3。
.DemoApp引用Facade和Facade.EF但不是实体框架 6.1.3。 NOR .DAL项目。即使在构建时将EF程序集添加到我的bin文件夹中,此项目也不会直接引用EF。
使用 .NET Framework 4.6.x 。,如果我尝试在DemoApp中对ApplicationDbContext进行编码,它会告诉我该类未定义,并且没有向我提供任何要添加的用法,这是预期的行为。
如果我尝试对 .NET Core 1.0 RC2 (通过使用Entity Framework Core)执行相同的操作,可以从.DemoApp访问ApplicationDbContext,而无需添加对.DAL项目的直接引用,这完全破坏了我的尝试隐藏实现细节。
<。> .DAL项目没有被.DemoApp项目直接引用 - 为什么我可以在那里看到它的类?这是预期的行为吗? 有没有办法让.NET Core项目具有与.NET Framework 4.6.x项目相同的行为?
答案 0 :(得分:8)
我几个月来一直苦苦挣扎,终于找到了一种方法来禁用Core中项目的传递引用。
在.Facade.EF的.csproj文件中,您可以将PrivateAssets="All"
添加到ProjectReference到.DAL:
<ItemGroup>
<ProjectReference Include="..\.DAL\.DAL.csproj" PrivateAssets="All" />
</ItemGroup>
使用此设置,引用.Facade.EF的项目也不再引用.DAL。
在更抽象的术语中,如果您希望A引用B和B来引用C,但不希望A引用C,请添加:
在B.csproj
<ItemGroup>
<ProjectReference Include="..\C\C.csproj" PrivateAssets="All" />
</ItemGroup>
答案 1 :(得分:4)
这是预期的行为。它被称为元包,例如用于NETStandard.Library
包以包含基类库的所有库。我认为没有办法隐藏它们。