我正在开发一个使用Unity Dependancy注入的项目,但负载性能正在慢慢恶化。我正在尝试调整代码以使用Lazy<T>
(或Func<T>
),因此我正在尝试使用Lazy<T>
(或{{1}找到使用容器注册类的方法或者有某种工厂,可以调整已注册的类型或构造函数,但我似乎无法找到可能的方法来做到这一点
目前我有很多服务类,比如
Func<T>
然后我的注册类似于
public Service1(IClassLogic<GetReq, GetRes> getClass, IClassLogic<AddReq, AddRes> addClass, IClassLogic<UpdateReq, UpdateRes> updateClass, IClassLogic<DeleteReq, DeleteRes> deleteClass....){...}
理想情况下,我不想将所有签名更改为
container.RegisterType<IClassLogic<GetReq, GetRes>, GetClass>();
container.RegisterType<IClassLogic<AddReq, AddRes>, AddClass>();
container.RegisterType<IClassLogic<UpdateReq, UpdateRes>, UpdateClass>();
container.RegisterType<IClassLogic<DeleteReq, DeleteRes>, DeleteClass>();
...
任何指针都会非常感激
答案 0 :(得分:2)
防止使用Lazy<T>
和{{1}}作为依赖关系来防止慢对象图初始化。这些是漏洞抽象,因为它们将实现细节泄露给消费者。这里的实现细节是这种服务的创建成本很高。
创建依赖关系花费太多时间这一事实表明您的注入构造函数做得太多,而它们应该是simple, fast and reliable。
另一个明显的问题是组件中的单一责任原则违规。在构造函数中具有5个以上的依赖项是代码气味和单一责任原则违规的指示。当你需要解决非常大的对象图时,有些容器会变慢,但是当你使你的组件变小并集中注意力时,这个问题很可能就会消失,因为要构造的对象图会小得多。
答案 1 :(得分:1)
首先关于DI的一些提示:
我编写了一个编译的快速示例(我还没有测试过)。我已经使用了一个与你的例子一致的通用接口,但是使用了一些伪实现和字符串类型作为泛型参数(未使用):
如果这是接口的实现:
public class ClassLogic : IClassLogic<string, string>
{
public void Do()
{
// do stuff
}
}
然后你可以实现一个只在需要时(通过给定的Func)创建实现的提供者,如下所示:
public class ClassLogicProvider : IClassLogic<string, string>
{
private readonly Func<IClassLogic<string, string>> innerLogicFactory;
public ClassLogicProvider(Func<IClassLogic<string, string>> innerLogicFactory)
{
this.innerLogicFactory = innerLogicFactory;
}
public void Do()
{
var classLogic = this.innerLogicFactory();
classLogic.Do();
}
}
然后将它连接起来:
var container = new UnityContainer();
Func<IClassLogic<string, string>> classLogicFunc = () =>
{
// Create implementation on demand
return new ClassLogic();
};
container.RegisterType<IClassLogic<string, string>>(
new InjectionFactory(c => {
return new ClassLogicProvider(classLogicFunc);
})
);
这应该为您提供所需的Lazy创建时间。