我一直使用Unity作为我的IoC容器一段时间,我找不到针对经常性问题的正确解决方案。我需要根据操作参数创建一些AuditInsertLogWriter和AuditUpdateLogWriter实例(它们实现IAuditOperationLogWriter接口),如下所示:
public IAuditOperationLogWriter Create(Operation operation)
{
switch (operation)
{
case Operation.Insert:
return UnityContainer.Resolve<AuditInsertLogWriter>();
case Operation.Update:
return UnityContainer.Resolve<AuditUpdateLogWriter>();
default:
break;
}
}
事情是,由于它们自己的依赖关系,这些实例的创建很复杂。此外,我想在这个工厂中删除Unity的依赖。所以,我的问题是:我怎样才能实现Unity根据某些上下文解析正确的类型?
答案 0 :(得分:3)
如果要删除工厂对容器的依赖性,则必须提前连接所有依赖项。
优雅的方法是Unity支持自动工厂。
您可以像这样定义工厂:
public class AuditOperationLogWriterFactory
{
private Dictionary<Operation, Func<IAuditOperationLogWriter>> auditCreator =
new Dictionary<Operation, Func<IAuditOperationLogWriter>>();
public AuditOperationLogWriterFactory(Func<AuditInsertLogWriter> insert,
Func<AuditUpdateLogWriter> update)
{
auditCreator[Operation.Insert] = insert;
auditCreator[Operation.Update] = update;
}
public IAuditOperationLogWriter Create(Operation operation)
{
if (auditCreator.ContainsKey(operation))
{
return auditCreator[operation]();
}
return null;
}
}
然后你可以解析工厂,Unity应该连接依赖项,并且对象创建被推迟到运行时(基于上下文)。如果它们很复杂,您可能需要通过配置(配置文件,代码或属性)来提供帮助。
IUnityContainer container = new UnityContainer();
var factory = container.Resolve<AuditOperationLogWriterFactory>();
var logWriter = factory.Create(Operation.Insert);
答案 1 :(得分:0)
您可以使用注册名称注册您的类型,注册名称可以是您的操作名称。在解决时,使用适当的名称,您将获得适当的注册。
请参阅UnityContainer的Register和Resolve方法的重载列表,并找到带有'name'参数的方法。这就是你要找的东西。