Unity - разрешение правильного экземпляра в зависимости от контекста - PullRequest
0 голосов
/ 22 декабря 2011

Я уже некоторое время использую 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 ]

3 голосов
/ 22 декабря 2011

Если вы хотите удалить зависимость фабрики от контейнера, вам придется заранее подключить все зависимости.

Элегантным способом сделать это была бы поддержка 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);
0 голосов
/ 22 декабря 2011

Вы можете зарегистрировать ваши типы, используя регистрационное имя, которое может быть именем вашей операции.При разрешении используйте соответствующее имя, и вы получите соответствующую регистрацию.

См. Список перегрузок методов Register и Resolve в UnityContainer и найдите те с параметром 'name'.Это то, что вы ищете.

...