如何在C#中共享3个项目之间的接口



我正在努力理解模块之间的共享接口,我遇到了以下问题:我有三个项目:

  • 控制台应用程序-是主项目,它想要获取数据
  • 核心库-是一个库,它决定将基于共享接口使用哪个数据服务
  • Data Library-提供必要数据的库

基本概念是,当我想在MySQL和SQL Server等数据库之间进行更改时,我不需要更改所有的基本代码,只需要更改一个模块,即数据库。多亏了核心库,其他项目不需要知道w Data Library中发生了什么,因为核心库是管理应该使用哪个类的库。

项目参考资料如下:

控制台应用程序-->核心库<--DataLibrary

因此,我创建了以下项目来解决这个问题。

控制台应用程序

class Program
{
static void Main(string[] args)
{
var core = new Core();
var dataService = core.GetDataService();
}
}

核心库

public class Core
{
public IDataService GetDataService()
{
return ???
} 
}
public interface IDataService
{
public IUserData UserData { get; set; }
}
public interface IUserData
{
public string Name { get; set; }
public string LastName { get; set; }
}

数据库

public class Data : IDataService
{
public IUserData UserData { get; set; }
}
public class UserData : IUserData
{
public string Name { get; set; }
public string LastName { get; set; }
}

在Core Library的方法GetDataService中,我无法返回Data的对象实例,因为它没有引用到DataLibrary。如果我反转它们之间的引用,我将无法实现CoreLibrary中的接口。在我想将两者相互引用的情况下,我得到一个错误";未能添加对"DataLibrary"的引用。将该项目添加为引用将导致循环依赖">

我犯了什么错误。这是一个好方法,但我遗漏了什么吗?或者可能整个事情都错了,我应该考虑其他解决方案?

Console应用程序是应用程序的启动路径,并且始终需要依赖于系统中的所有其他库。即使Console应用程序也不会直接依赖于数据访问库,如果没有这种间接依赖,它也无法编译和运行。换句话说,程序集依赖关系是可传递的。在这方面,这个问题的答案中有丰富的信息,你当然应该核实。这里重复太多了。

防止从启动路径到程序集的依赖关系的唯一方法是使用后期绑定。这意味着您可以在启动时将程序集动态加载为插件。尽管在理论上,您可以在中加载插件。NET在几行代码中,这样的插件暴露的合同越宽,设计和设置插件系统的工作就越多。例如,如果每个插件只包含实现单个IPlugin接口的插件,则加载相当容易,但随着实现的接口数量的增加,加载会变得更加困难。最终,您将得到插件程序集,这些插件程序集包含构建对象图的逻辑的各自部分,可能与使用的DI容器库集成。

后期绑定通常不太适合像数据访问层这样的库,因为它们通常会公开广泛的API。只要不需要在不需要重新编译软件的情况下动态切换数据访问技术,就应该防止后期绑定给表带来的复杂性。

依赖注入(DI(的一个常见做法是使应用程序的入口点成为创建所有应用程序组件(包含应用程序行为的类(的地方。在DI术语中,这个地方被称为组合根。

这意味着Console应用程序本身是创建Data Library的Data类的最合理的地方。例如,像这样:

class Program
{
static void Main(string[] args)
{
var dataService = new DataLibrary.Data();
var appService = new CoreLibrary.ApplicationService(dataService);
appService.DoSomething();
}
}

这种方法允许中央核心库保持隔离,允许将来交换数据访问层,Main方法的唯一职责是将所有内容"捆绑"在一起并启动应用程序。

实现这一点的关键是"反转"从核心库到数据访问库的依赖关系。这就是您通过让DataLibrary依赖于CoreLibrary所做的。正因为如此,您正在应用依赖反转原则,它提倡这种反转。

最新更新