Прежде всего, вы можете пересмотреть свою архитектуру.Например, как насчет ожидания, пока вы не узнаете, к какому типу приложения вы принадлежите, прежде чем регистрировать выходной сервис.Тогда вы можете просто зарегистрировать тот, который вам нужен.Или вы могли бы добавить дополнительный уровень косвенности, попросив другую службу предоставить вам OutputService, и он мог бы знать, в каком режиме работает ваше приложение.
Но то, что вы просили сделать, возможно с единством.Есть два подхода.Во-первых, это использование InjectionConstructor
с двумя ResolvedParameter
s - это позволяет указать именованную службу вывода для использования.Тем не менее, он хрупок, поскольку, если вы реорганизуете конструктор Calculator, вы узнаете его только во время выполнения.
Так что лучшим подходом является InjectionFactory
, где вы предоставляете ему Func, который создает ваш объект калькулятора.Этот Func может получить доступ к контейнеру, так что он может делать именованные разрешения.Вот проходной юнит-тест, который делает то, что вы хотите:
[Test]
public void NamedDependenciesTest()
{
IUnityContainer container = new UnityContainer();
container.RegisterType<IInputService, ConsoleInputService>();
container.RegisterType<IOutputService, ConsoleOutputService>("Console");
container.RegisterType<IOutputService, MessageBoxOutputService>("Window");
container.RegisterType<ICalculator>("Cal1", new InjectionFactory((c) => new Calculator(c.Resolve<IInputService>(), c.Resolve<IOutputService>("Console"))));
container.RegisterType<ICalculator>("Cal2", new InjectionFactory((c) => new Calculator(c.Resolve<IInputService>(), c.Resolve<IOutputService>("Window"))));
// alternative setup with ResolvedParameter:
//container.RegisterType<ICalculator, Calculator>("Cal1", new InjectionConstructor(new ResolvedParameter(typeof(IInputService)), new ResolvedParameter(typeof(IOutputService), "Console")));
//container.RegisterType<ICalculator, Calculator>("Cal2", new InjectionConstructor(new ResolvedParameter(typeof(IInputService)), new ResolvedParameter(typeof(IOutputService), "Window")));
var cal1 = container.Resolve<ICalculator>("Cal1");
Assert.IsInstanceOf<ConsoleOutputService>(cal1.OutputService);
var cal2 = container.Resolve<ICalculator>("Cal2");
Assert.IsInstanceOf<MessageBoxOutputService>(cal2.OutputService);
}
interface IInputService { }
interface IOutputService { }
interface ICalculator { IOutputService OutputService { get; } }
class ConsoleInputService : IInputService { }
class ConsoleOutputService : IOutputService { }
class MessageBoxOutputService : IOutputService { }
class Calculator : ICalculator
{
public Calculator(IInputService input, IOutputService output) { this.InputService = input; this.OutputService = output; }
public IInputService InputService { get; private set; }
public IOutputService OutputService { get; private set; }
}