当给定接口有多个命名实现时,容器(我在Prism应用程序中使用Unity)如何知道要注入哪个,除非我调用容器。使用注册名称解析?这是一个简单的例子:
public interface IDependencyClass
{
void DoSomething();
}
public class DependencyClassA : IDependencyClass
{
void DoSomething() { }
}
public class DependencyClassB : IDependencyClass
{
void DoSomething() { }
}
public interface IConsumer
{
void TakeUserSpecificAction();
}
public class Consumer : IConsumer
{
IDependencyClass dependencyInstance;
public Consumer(IDependencyClass _dependencyInstance)
{
dependencyInstance = _dependencyInstance;
}
public void TakeUserSpecificAction()
{
dependencyInstance.DoSomething();
}
}
public class MyBootStrapper : UnityBootstrapper
{
protected override void ConfigureContainer()
{
base.ConfigureContainer();
Container.RegisterType<IDependencyClass, DependencyClassA>( "InstanceA" );
Container.RegisterType<IDependencyClass, DependencyClassB>( "InstanceB" );
Container.RegisterType<IConsumer, Consumer>();
}
}
这是我的应用程序中的MainViewModel。在用户登录之前,不会启用“RaiseSomeCommand”命令。启用后,它可以执行ReaiseConsumerCommandRequest,后者又调用消费者。这是我的ViewModel。
public class MainWindowViewModel
{
private readonly IRegionManager regionManager;
private readonly ILoginService loginService;
private readonly IConsumer consumer;
public ICommand RaiseSomeCommand { get; set; }
public MainWindowViewModel( IRegionManager regMgr, ILoginService _loginService, IConsumer _consumer )
{
regionManager = regMgr;
loginService = _loginService;
consumer = _consumer;
NavigateCommand = new DelegateCommand<string>( Navigate );
LoginViewRequest = new InteractionRequest<INotification>();
RaiseSomeCommand = new DelegateCommand( RaiseConsumerCommandRequest );
}
private void RaiseConsumerCommandRequest()
{
consumer.TakeUserSpecificAction();
}
}
所以,当我执行
时consumer.TakeUserSpecificAction();
我使用的是哪个DependencyClass实例? DependencyClassA或DependencyClassB。另外,如果我想特别使用DependencyClassB,我需要做些什么来实现它。我不想打电话
container.Reslove<IDependencyClass>("InstanceB")
在我的ViewModel中,因为我正在使用容器作为服务定位器。我也传递了容器参考。
我在一些代码示例中看到,使用者的构造函数参数使用如下的Dependency属性进行修饰。
public class Consumer
{
IDependencyClass dependencyInstance;
public Consumer([Dependency("InstanceB")]IDependencyClass _dependencyInstance)
{
dependencyInstance = _dependencyInstance;
}
}
但是,我对消费者施加了一个严格的限制,只使用“InstanceB”实现。其次,我正在创建对Unity的依赖。第三,现在我必须克隆Consumer类以使用“InstanceA”实现。这与DRY原则背道而驰。
我听说这些条件是应用程序决策而不是IoC相关逻辑。我同意这个论点。但是,在应用程序中的哪个位置和方式如何解决正确的实现而不违反一个或另一个规则?
除非我选择使用上述两个选项之一,否则我无法看到如何注入正确的具体实例。 Container.Resolve或Dependency属性。有人可以帮忙吗?