Unity - как использовать несколько отображений для одного типа и внедрить в объект - PullRequest
4 голосов
/ 26 марта 2011

Я использую Unity 2.0 и в следующем коде я пытаюсь внедрить определенный инструмент в объект Worker.

Я хотел бы использовать следующий код. Но, конечно же, возникает ошибка «Не удалось разрешить зависимость». Я верю, что смогу сделать что-то подобное, но мне трудно это понять.

IUnityContainer container = new UnityContainer();
container.RegisterType<IWorker, Worker>("Worker")
    .RegisterType<ITool, ToolA>("ToolA")
    .RegisterType<ITool, ToolB>("ToolB")
    .RegisterType<ITool, ToolC>("ToolC");

IWorker worker = container.Resolve<Worker>("ToolA");

Я знаю, что это не работает, но как мне решить эту проблему?

BarDev

1 Ответ

9 голосов
/ 26 марта 2011

Это можно сделать двумя способами:

Вы можете использовать ParameterOverride и двухэтапный процесс разрешения ...

var tool = container.Resolve<ITool>("ToolB");
var worker = container.Resolve<IWorker>("Worker", 
    new ParameterOverride("tool", tool));

... при условии, что аргумент конструктора в Worker, который получает ITool, называется 'инструментом' (несколько ParameterOverride экземпляров могут быть переданы в Resolve). Любые другие зависимости (через конструктор или внедрение свойства), которые имеет именованный экземпляр IWorker, также должны быть правильно разрешены.

В качестве альтернативы, почему бы не настроить именованные WorkerA, WorkerB, WorkerC экземпляры, которым требуется указанный ITool ...

container.RegisterType<ITool, ToolA>("ToolA");
container.RegisterType<ITool, ToolB>("ToolB");
container.RegisterType<ITool, ToolC>("ToolC");
container.RegisterType<IWorker, Worker>("WorkerA", 
    new InjectionConstructor(new ResolvedParameter<ITool>("ToolA")));
container.RegisterType<IWorker, Worker>("WorkerB", 
    new InjectionConstructor(new ResolvedParameter<ITool>("ToolB")));
container.RegisterType<IWorker, Worker>("WorkerC", 
    new InjectionConstructor(new ResolvedParameter<ITool>("ToolC")));

Недостаток, который, как я полагаю, связан с последним подходом, заключается в том, что если Worker принимает дополнительные параметры конструктора, вам нужно будет также указать их для InjectionConstructor, заданного в том же порядке, что и конструктор, который вы ожидаете использовать в Unity. ..

container.RegisterType<IWorker, Worker>("WorkerA", 
    new InjectionConstructor(typeof(SomeDependency), new ResolvedParameter<ITool>("ToolA"), typeof(SomeOtherDependency));

Однако Unity будет искать безымянный экземпляр SomeDependency и SomeOtherDependency в приведенном выше примере, так что это сэкономит вам немного времени.

...