我有一个名为Foo的DNX 4.5.1 ASP.NET 5项目和一个名为Bar的类库项目。 Foo引用了Bar,而Bar引用了一个名为Baz的nuget包。
在Foo中,我可以使用Baz中定义的类型,尽管Foo没有引用nuget包。似乎Foo可以访问Bar引用的任何类型。这是为什么?这不完全打破抽象的概念吗?
答案 0 :(得分:1)
不,只要你在Foo中安装Baz NuGet包,它也不会破坏抽象,因为你声明了一个依赖。 Baz库具有公共类的简单事实意味着任何引用它的exe或dll文件都可以使用这些类。
由于Foo需要Bar,而Bar需要Baz,因此在编译Foo时,Baz.dll文件应出现在bin/
输出文件夹中,因为Foo需要Bar中的类。这意味着Foo文件顶部的简单using
指令会导致CLR导入Baz.dll文件。
现在如果Foo需要直接使用Baz中定义的类,我建议安装Baz项目作为Foo的依赖。两个库需要相同的第三方库是可以的。你只需要确保Foo和Bar都需要相同的版本。
如果Foo和Bar需要不同的版本,那么我建议在Bar中创建代理类或接口来封装Baz所需的行为,这样Foo项目就不需要直接了解Baz。
让我们做一个具体的例子。
没有潜水太深或对#34;最佳实践和#34;做出任何判断这个例子围绕着一个博客的ASP.NET MVC项目。它有一个用于数据访问和业务类的类库。该库安装了NHibernate NuGet包。
Foo是" Blog.Mvc" project,ASP.NET MVC应用程序
Bar是" Blog.Core" project,包含存储库类和接口的类库,以及" Domain Models"或商务舱。
Baz是NHibernate
所以问题就变成了:
" Blog.Mvc"应用程序直接使用NHiberate中的类?
没有。 " Blog.Core"项目应该使用存储库接口提供一个抽象层:
首先,"域模型"或商务舱:
public class Blog
{
public virtual int Id { get; protected set; }
public virtual string Name { get; set; }
}
博客存储库的公共接口:
public interface IBlogRepository
{
Blog Find(int id);
}
现在实现接口,引用与NHibernate直接相关的类和接口:
public class BlogRepository : IBlogRepository
{
private NHibernate.ISession session;
private NHibernate.ISession Session
{
get
{
if (session == null)
session = NHibernateSessionHelper.GetSession();
return session;
}
}
public Blog Find(int id)
{
return Session.Get<Blog>(id);
}
}
MVC项目控制器通过其界面使用存储库:
public class BlogsController : Controller
{
public BlogsController(IBlogRepository repository)
{
this.repository = repository;
}
private IBlogRepository repository;
public ActionResult Edit(int id)
{
Blog blog = repository.Find(id);
if (blog == null)
return HttpNotFound();
BlogForm viewModel = new BlogForm(blog);
return View(viewModel);
}
}
虽然这可能不是您的确切情况,但此示例中概述的“关注点分离”使您的问题没有实际意义。
如果Foo需要Baz中的类,请将其声明为依赖项。如果没有,请不要在Foo项目中使用Baz中声明的类。如果Foo需要Bar的功能,它将某些行为委托给Baz,只要Foo没有传递Baz中定义的类的任何对象,这就不会破坏抽象。 Bar需要创建它自己的类作为数据传输对象,代理类或某种实现Bar中定义的接口以供Foo使用的对象。