我的Web API解决方案有3个项目:控制器层,业务层,数据访问层。 Unity安装在控制器层项目中以实现DI。业务和数据层中的每个类都有一个与之关联的接口。现在我如何从A业务层访问B业务层中的功能,同时遵守DI标准? Unity未安装在业务层项目中。 目前我在做的是:
public class BBusiness
{
IBDataAccess bDataAccess;
IADataAccess aDataAccess;
public BBusiness(IBDataAccess bDataAccessParam, IADataAccess
aDataAccessParam)
{
this.bDataAccess=bDataAccessParam;
this.aDataAccess=aDataAccessParam;
}
public function()
{
ABusiness obj=new ABusiness(this.aDataAccess);
obj.functionInABusiness();
}
}
答案 0 :(得分:0)
据我所知(我是DI的新手),你不应该在ABusiness
中创建一个对象BBusiness
。
你应该做的是像
public function()
{
aDataAccess.functionInClassThatImplementsInterfaceIADataAccess();
}
您的解决方案意味着,BBusiness仍然依赖于ABusiness,您希望通过使用DI来避免这种情况。
答案 1 :(得分:0)
这是层的整体思路:你不从A中访问B中的函数.A忙于自己的业务,甚至不知道B. B的存在,但是,知道A ,了解A的事件(A提供的任何事件)并对它们做出反应。
答案 2 :(得分:0)
由于ABusiness
是 某项服务,因此通常会将其设置为:
public interface IABusiness
{
void functionInABusiness();
}
public class ABusiness : IABusiness
{
// making the variable private readonly ensures that nothing
// can set it after the constructor does (thus it can never be null)
private readonly IADataAccess aDataAccess;
public ABusiness(IADataAccess aDataAccessParam)
{
// Guard clause ensures you cannot set this.aDataAccess to null
if (aDataAccessParam == null)
throw new ArgumentNullException(nameof(aDataAccessParam));
this.aDataAccess=aDataAccessParam;
}
public void functionInABusiness()
{
// Do something with aDataAccess
}
}
然后,您将添加IABusiness
作为BBusiness
的依赖项。
public interface IBBusiness
{
void function();
}
public class BBusiness : IBBusiness
{
private readonly IBDataAccess bDataAccess;
private readonly IABusiness aBusiness;
public BBusiness(IBDataAccess bDataAccessParam, IABusiness aBusinessParam)
{
if (bDataAccessParam == null)
throw new ArgumentNullException(nameof(bDataAccessParam));
if (aBusinessParam == null)
throw new ArgumentNullException(nameof(aBusinessParam));
this.bDataAccess=bDataAccessParam;
this.aBusiness=aBusinessParam;
}
public function()
{
this.aBusiness.functionInABusiness();
// Do something else...
}
}
在composition root中,您可以设置Unity将IABusiness
与ABusiness
和IBBusiness
与BBusiness
相关联。请注意,如果类和接口以某种方式命名或放在某个位置等,某些项目会使用自动执行此步骤的约定。
container.RegisterType<IABusiness, ABusiness>();
container.RegisterType<IBBusiness, BBusiness>();
container.RegisterType<IADataAccess, ADataAccess>();
container.RegisterType<IBDataAccess, BDataAccess>();
整个想法是您不直接从ABusiness
类引用BBusiness
类,因此您可以将IABusiness
的不同实例注入BBusiness
(对于测试,或创建围绕IABusiness
的装饰器类,增加了对它的额外责任等。)
此外,IABusiness
接口可能与ABusiness
不同的程序集(例如),因此BBusiness
程序集不需要引用ABusiness
程序集
请注意,您没有关注Microsoft的capitalization conventions,这可能会使跟踪您的代码难以维护。方法名称应该是.NET中的Pascal大小写,如
FunctionInABusiness()
。