为什么Microsoft.Practices.ServiceLocation.IServiceLocator不提供TryGetInstance()?
我需要获取通用验证器实例ServiceLocator.Current.GetInstance<IEntityValidator<TEntity>>(),但并不是所有实体都注册了验证器。
我找到的唯一解决方案是使用try{}catch{}块,但我不喜欢这种方法。
发布于 2010-04-12 16:54:16
我不能告诉你为什么这个方法不存在,但我想提供一个观点,它不应该影响,因为在任何情况下,你都不应该以基于pull的方式使用DI容器。这是Service Locator anti-pattern。
如果您需要IEntityValidator<Foo>,则通过构造函数请求依赖项:
public class Foo
{
private readonly IEntityValidator<Foo> validator;
public Foo(IEntityValidator<Foo> validator)
{
this.validator = validator;
}
}您可以通过不同的方式处理并非所有实体都注册了验证器的问题。
我的首选方法是为所有这些实体注册一个Null Validator。
或者,您可以为实体提供一个不带验证器的构造函数重载,然后从该构造函数分配一个Null validator。它可能看起来像这样:
public class Foo
{
private readonly IEntityValidator<Foo> validator;
public Foo()
{
this.validator = new NullValidator<Foo>();
}
public Foo(IEntityValidator<Foo> validator)
{
this.validator = validator;
}
}然而,这是否有效部分取决于您特定的DI容器。例如,Castle Windsor使用它能满足的最贪婪的构造函数,所以在这种情况下,即使在没有注册验证器的情况下,它也可以很好地工作,因为它只会选择默认的构造函数。
在任何情况下,基于推送的方法都是真正的依赖注入。通过这种方法,您可以使用DI容器来resolve the entire dependency graph in one go at the application's entry point。
发布于 2010-04-12 17:53:00
CSL不支持这种机制的原因是不是所有的IoC框架都支持这种机制。通用服务定位器讨论论坛提供了解决此问题的方法。Read this question。
我同意Mark的观点,如果可以的话,你应该尝试注册一个空对象,并尽可能坚持使用真正的依赖注入。
https://stackoverflow.com/questions/2620675
复制相似问题