在静态构造函数中初始化容器

时间:2015-09-17 10:59:46

标签: c# simple-injector

在静态构造函数中初始化简单注入器容器是否合法?

示例:

using SimpleInjector;

public static Bootstrapper
{
    private readonly static Container container;

    static Bootstrapper()
    {
        Bootstrapper.container = new Container();
    }
}

3 个答案:

答案 0 :(得分:3)

正如@NedStoyanov所说,静态构造函数可以保证唯一性,因此这可能是有益的。然而,静态构造函数的缺点是它们通常更难以调试,并且从cctor主体抛出的任何异常都包含在InitializationException中,这使得查看实际问题变得更加困难。

我还想重复@ WSriramSakthivel的警告:尽管在撰写根目录中将Container声明为public readonly static字段,但阻止从外部组合根访问此字段,只要有可能。从组合根外部使用它意味着应用Service Locator anti-pattern

请注意,使用cctor初始化容器也会有缺点。在集成测试中验证容器并运行一些使用容器构建对象图的集成测试时,通常希望让每个测试都有自己的容器实例,并且配置略有不同。这是使用cctor时无法正常工作的内容。

这么长的故事很简短,虽然使用一个cctor可能会很好并提供一些很好的保证,但我认为在大多数情况下,它只会妨碍它。

答案 1 :(得分:2)

根据我的经验,在大多数情况下,您应该尽量避免使用静态实例。想象一下,容器的生命周期与应用程序的生命周期相匹配。换句话说,如果您将容器设为静态,它将保持活动状态,直到应用程序关闭。

要获得更好的练习,请找到您的应用程序的入口点。我们假设它是 static void Main()。在这种情况下,请在此处创建容器的实例,并使用此容器创建启动对象(Windows,Forms等)。

如果您正确设计DI,则稍后您不应该在应用程序中使用容器对象。只需确保服务(使用容器注册)在需要时通过构造函数注入对象。

另外,请查看Service Locator violates SOLID by Mark Seemann。马克有很多关于DI的帖子,并解释了为什么这是一个不好的做法。

答案 2 :(得分:1)

应该没问题,static构造函数只保证在第一次使用类型之前调用一次并且是线程安全的。

来自特征

  

静态构造函数不是继承的,不能直接调用。   封闭类类型的静态构造函数在给定的应用程序域中最多执行一次。

     

静态构造函数的执行由应用程序域中发生的以下第一个事件触发:
  •创建类类型的实例   •引用类类型的任何静态成员。