将类实例传递给静态"容器类"

时间:2017-07-19 11:11:55

标签: c# dependency-injection

在应用程序启动时将创建的类的实例传递给静态容器类是非常好的做法,静态容器类只有getter和setter来获取实例,或者是单身人士的用例?

在我的情况下,该类是当前登录用户的表示。

例如:

class ClassA
{}

class ClassB
{
    public void UseClassA()
    {
        ClassA classA = Container.ClassA;
    }
}

class ApplicationStart
{
    public void Main()
    {
        Container.ClassA = new ClassA();
    }
}

static class Container
{
    private static ClassA classA;
    public static ClassA ClassA
    {
        get { return classA; }
        set { classA = value; }
    }
}

2 个答案:

答案 0 :(得分:1)

  

将应用程序启动时只创建一次的类的实例传递给其他类

是一种好习惯

是的!这称为依赖注入(DI),因为您将每个对象的依赖项注入构造函数参数。应用程序入口点称为" composition root "用DI的说法:

  

组合根是应用程序中(最好)唯一的位置,其中模块组合在一起。

通过构造函数将对象传递给其他对象称为构造函数注入模式。

  

一个静态容器类,它只有getter和setter来获取实例,或者是单例的用例?

使用单身几乎肯定更糟。

Here's Mark's commentary on a similar question

  

如果您将容器用作服务定位器,那么您是对的   或多或少是一个美化的静态工厂。出于很多原因我   认为这是一种反模式。

     

构造函数注入的一个很好的好处就是它   明显违反单一责任原则   明显。

     

当发生这种情况时,是时候重构Facade Services了。简而言之,   创建一个隐藏交互的新的,更粗粒度的界面   您当前的部分或全部细粒度依赖关系之间   需要。

创建"真实"单例类是almost certainly worse,而不是实例化你的对象,并把它交给需要它作为构造函数参数的其他对象。

在你的情况下,我会做这样的事情:

static void Main()
{
    // This is your composition root
    var numberProvider = new NumberProvider();
    var b = new B(numberProvider);
    b.DoSomething();
}

class NumberProvider
{
    private int _number = 0;

    // In the real world, maybe this gets a value from a web service
    // and implements an INumberProvider interface so you can mock it
    // for unit testing
    public int GetNumber() => _number++;
}

class B
{
    private readonly NumberProvider _numberProvider;

    public B(NumberProvider numberProvider)
    {
        _numberProvider = numberProvider;
    }

    public void DoSomething()
    {
        Console.WriteLine(_numberProvider.GetNumber());
    }
}

避开公共制定者。很有可能,你不需要公开所有东西。

答案 1 :(得分:0)

所以,你问这个单独的单身人士是否更好,如下:

public class Singleton1
{
    public static Singleton1 Instance { get; set; }
}

public class Singleton2
{
    public static Singleton2 Instance { get; set; }
}

或单个Container将所有这些内容放在一个位置:

public static class Container
{
    public static Singleton1 FirstSingleton { get; set; }
    public static Singleton2 SecondSingleton { get; set; }
}

由于它们在技术上相同,这是一种基于意见的困境。这取决于你对一方或另一方的感受。

一个更有趣的问题可能是:我应该使用静态Container还是更高级(但更复杂)的技术,例如依赖注入依赖容器< / em>的? 但同样,这取决于您的需求。如果你只需要几个简单的单身,一个简单的静态Container就好了(记住金色的KISS原则:保持简单,愚蠢!)。除非您使用它来存储特殊对象,例如经过身份验证的用户:在这种情况下,它应该由身份验证类和策略管理,如@Yeldar指出的那样。