显示 .NET Core 中间接引用的包中的类

Posted

技术标签:

【中文标题】显示 .NET Core 中间接引用的包中的类【英文标题】:Showing classes from indirectly referenced packages in .NET Core 【发布时间】:2016-10-24 03:06:15 【问题描述】:

我正在尝试使用 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 项目相同的行为?

【问题讨论】:

有人添加了正确答案 (PrivateAssets=All) - 你能接受吗? @PeterMorris 我已经接受了答案。感谢您指出! 【参考方案1】:

我已经为此苦苦挣扎了几个月,终于找到了一种方法来禁用 Core 中项目的传递引用。

在 .Facade.EF 的 .csproj 文件中,您可以将 PrivateAssets="All" 添加到 .DAL 的 ProjectReference 中:

<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>

来源:https://github.com/dotnet/project-system/issues/2313

【讨论】:

这不起作用,因为一旦您将所有资产设为私有代码,内部使用该类型的代码将不再编译。换句话说,当 A 使用 B(使用 C)时,A 将不会编译,直到对 C 的引用添加到 A。【参考方案2】:

这是预期的行为。它被称为元包,例如用于NETStandard.Library 包以包含基类库的所有库。我认为没有办法隐藏它们。

【讨论】:

抛开你的问题,我个人的看法是,将工件隐藏在参考树后面可能对开发人员的纪律很有用,但不会带来任何架构上的好处。当您添加对实现的引用(即此处.Facade.EF)时,您会破坏所有基于模式的隐藏。如果你通过 IoC/依赖注入来做到这一点,那么模式就会起作用,你的可见性问题就会消失。我还认为,隐藏 Product 类并在存储库中提供诸如 GetName 之类的方法并不能反映存储库模式。

以上是关于显示 .NET Core 中间接引用的包中的类的主要内容,如果未能解决你的问题,请参考以下文章

10分钟学会Visual Studio将自己创建的类库打包到NuGet进行引用(net,net core,C#)

java中,引用另一个包中的类做父类时,显示程序包不存在怎么办

Composer,我的包中的类没有在使用它的应用程序中自动加载

无法加载从带有标识符的包中的笔尖引用的图像

在java中怎样在有名包中引用无名包中的类

xcassets 中的所有图像,然后如何加载从我的包中的 nib 引用的图像