为什么Microsoft.Practices.ServiceLocation.IServiceLocator
不提供TryGetInstance()?
我需要获得通用验证器实例ServiceLocator.Current.GetInstance<IEntityValidator<TEntity>>()
,但并非所有实体都注册了验证器。
我找到的唯一解决方案是使用try {} catch {}块,但我不喜欢这种方法。
答案 0 :(得分:4)
我不能告诉你为什么这种方法不存在,但是我想提供一个选择不重要,因为你不应该在<中使用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。
答案 1 :(得分:3)
CSL不支持这一点的原因是并非所有IoC框架都支持这种机制。 Common Service Locator讨论论坛针对此问题提供了解决方法。 Read this question。
我同意Mark的意见,你应该尝试注册一个 Null Object ,如果可能的话,坚持使用真正的依赖注入。