Microsoft.Practices.ServiceLocation和TryGetInstance

时间:2010-04-12 08:23:44

标签: .net ioc-container

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

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

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

2 个答案:

答案 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 ,如果可能的话,坚持使用真正的依赖注入。