2010-04-12 18 views
1

为什么Microsoft.Practices.ServiceLocation.IServiceLocator不提供TryGetInstance()?Microsoft.Practices.ServiceLocation和TryGetInstance

我需要获得通用验证器实例ServiceLocator.Current.GetInstance<IEntityValidator<TEntity>>()但并非所有实体都已注册验证器。

我发现的唯一解决方案是使用try {} catch {}块,但我不喜欢这种方法。

回答

4

我不能告诉你为什么这个方法不存在,但我想提供opion是因为你不应该在一个拉基于使用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验证器。这可能看起来像这样:

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

3

CSL不支持的原因是并非所有的IoC框架都支持这种机制。 Common Service Locator讨论论坛为此问题提供了一种解决方法。 Read this question

我同意马克,你应该尝试注册一个空对象是你可以并在可能时坚持真正的依赖注入。

相关问题