Unity - 根据上下文解析正确的实例

时间:2011-12-21 21:07:25

标签: c# inversion-of-control unity-container factory-pattern

我一直使用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根据某些上下文解析正确的类型?

2 个答案:

答案 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'参数的方法。这就是你要找的东西。