我有一个简单的.NET项目,我想知道什么是引导Unity的最佳方法。 我开始使用带有一堆控制器的WebApp。每个控制器都有自己的Handler类,控制器委托实现。有些东西:
public class UsersHandler : IUsers
{
IAuthenticationClient authenticationClient;
ILogger logger;
public UsersHandler(IAuthenticationClient authClient, ILogger logger) { ... }
}
在Global.asax的Application_Start方法中,我正在创建UnityContainer并注册类型。 还有第二个项目(类库),它基本上是业务层。
我现在创建了一个新的类库(让我们称之为'XYZ')来处理应用程序的不同责任。 DI也在这里使用。
对于初学者,我创建了一个Singleton类,它将作为此项目的入口点,我将实例化UnityContainer和寄存器类型。
现在我已经开始工作,我开始想知道谁应该处理类型注册,这意味着应该是我的应用程序的组合根。 WebApp将是第一选择,但这需要添加对'XYZ'项目的引用,因为业务层使用它,所以感觉不对。
1)Composition根应该是一个引用WebApp和'XYZ'并在我的WebApp的global.asax中初始化的新类库吗? 但是,这会导致循环依赖,因为此Bootstrapper项目将知道WebApp,反之亦然。
2)如果我需要在'XYZ'项目中解决依赖关系怎么办?目前我有一个UnityContainer类的实例,所以我能够这样做:
var logger = container.Resolve<ILogger>();
这是一个好的做法吗?
答案 0 :(得分:3)
喜欢this很棒的回答说
&#34;应用程序中的所有组件应该最晚组成 可能&#34;
然后你应该在WebApp项目的global.asax中组合它们。 所有这些(基本上回答了这两个问题)。
组合根是应用程序中所有模块组合的地方。 在您的情况下,WebApp将成为该项目,因此应该参考解决方案中的所有项目。 WebApp应该引用Business Layer,XYZ和您添加的所有其他项目。
&#34;但是,这会导致循环依赖。&#34;
不,只有合成根指的是解决方案中的项目。
但是业务层和XYZ如何相互协作呢?
他们没有。 DIP的核心原则是依赖于抽象,并在您的解决方案中充分使用DIP,您需要正确设计代码。
假设我们在业务层项目中有一个对XYZ项目具有依赖性的类
using XYZ;
namespace BusinessLayer
{
public class businessData
{
public int GetData()
{
var data = new XYZData(); //from the XYZ project
return data
}
}
}
这个类在XYZ项目中
namespace XYZ
{
public class XYZData
{
public int GetData()
{
return 1;
}
}
}
现在我们拥有项目BusinessLayer和XYZ之间的依赖关系。 为了解决这个问题,我们需要使BusinessLayer中的businessData依赖于抽象而不是细节。
要做到这一点,我们需要使用Interfaces来消除类之间的依赖关系,并且当它们被处理时,我们不需要在BusinessLayer项目中引用XYZ,因为它&#39;不再使用了。
但我们在哪里存储界面?
为此,您将创建一个ModelProject,解决方案中的所有项目都将引用该模型。 ModelProject不涉及任何东西,因为它的目的是仅存储DTO和接口等。
作为组合根的WebApp应该引用解决方案中的所有项目。其余项目应仅参考ModelProject
要解决businessData中的依赖性,请将此接口添加到Modelproject
namespace Modelproject
{
public interface IXYZData
{
int GetData();
}
}
然后在类
中实现接口对于商业项目
using Modelproject;
namespace BusinessLayer
{
public class businessData
{
private IXYZData _data;
public businessData(IXYZData data)
{
this._data = data;
}
public int GetData()
{
return _data.GetData();
}
}
}
对于XYZ项目
using Modelproject;
namespace XYZ
{
public class XYZData: IXYZData
{
public int GetData()
{
return 1;
}
}
}
然后在WebApp的global.asax中,使用XYZData类解析接口IXYZData。 通过Unity将是
var container = new UnityContainer();
container.RegisterType<IXYZData, XYZData>(new HierarchicalLifetimeManager());
GlobalConfiguration.Configuration.DependencyResolver = new UnityResolver(container);
希望这会有所帮助,欢呼
<强>更新强>
如果要在另一个类中使用businessData类,则应该应用与添加接口的XYZData类相同的结构。
namespace Modelproject
{
public interface IbusinessData
{
int GetData();
}
}
然后将接口继承添加到类
using Modelproject;
namespace BusinessLayer
{
public class businessData: IbusinessData
{
.....
最后告诉Global.asax中的Unity容器解析类
的接口container.RegisterType<IbusinessData, businessData>(new HierarchicalLifetimeManager());
现在,在您需要使用IbusinessData的每个类中,将它添加到类的构造函数中,就像我们在businessData构造函数中所做的那样,然后Unity将确保在运行时创建该类时注入所有依赖项。
答案 1 :(得分:0)
container.Resolve<IDependency>()
你可以在这里阅读一篇非常好的文章https://www.asp.net/web-api/overview/advanced/dependency-injection