服务地点方便

时间:2013-11-27 15:01:48

标签: c# .net dependency-injection service-locator

我对以下代码段有2个问题:

public class Provider
{
    private static Provider _instance;

    /* Internals ommited. */

    public static Provider Instance
    {
        get { return _instance ?? (_instance = new Provider()); }
    }
}

public class Consumer
{
    private readonly Provider _dependency;

    public Consumer()
        : this(Provider.Instance)
    {
    }

    public Consumer(Provider dependency)
    {
        _dependency = dependency;
    }

    /* Internals ommited. */
}

1)第二个构造函数使用依赖注入模式,第一个做什么?服务地点?

2)通常的做法是提供使用默认实例的这种过载的ctor吗?或者有更好的方法来做这样的事情? (我想避免实现包装类)。

2 个答案:

答案 0 :(得分:1)

  

第二个构造函数使用依赖注入模式,是什么   第一个在做什么?服务地点?

假设Provider是依赖本身而不是某种注册表然后没有,它仍然是依赖注入。为方便起见,您只是为依赖项提供默认值。

  

通常的做法是提供这样一个使用a的过载的ctor   默认实例?或者有更好的方法来做这样的事情?   (我想避免实现包装类)。

这绝对没问题,但您可能需要将工厂方法视为默认构造函数的替代方法:

public static Consumer CreateDefault()
{
    return new Consumer(Provider.Default);
}

通过这种方式,您可以避免客户掩盖默认构造函数代表他们做出(可能很重要)选择的事实。

答案 1 :(得分:1)

1)第一个构造函数使用静态依赖注入。此模式允许从Provider派生的类被注入用于测试目的,或者作为运行时默认Provider实现的替代。 Provider本身可能是服务定位器 - 取决于它实际提供的对象或服务。

但是,在此示例中,Provider被注入Consumer。这是依赖注入,而不是服务定位器(它需要一个类来确定它自己的依赖关系,导致它们之间的紧密耦合)。由于依赖注入,Consumer类如果获得Provider的默认实现,或者从它派生的类,则无关紧要。如果a)Provider是一个接口,那么这些类可以更松散地耦合,并且b)如果客户端代码总是确定要注入哪个实例,而不是具有默认值。

2)就个人而言,我认为静态提供程序是代码味道,但它们确实有效,并且可能完全适合您的代码库。理想情况下,Provider应该是依赖注入框架注入的单例工厂。我现在在代码库中有静态提供程序,我正在慢慢地用这种方式替换它们。 Consumer应该有一个构造函数 - 第二个。