Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/264.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在静态构造函数中初始化容器_C#_Simple Injector - Fatal编程技术网

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

C# 在静态构造函数中初始化容器,c#,simple-injector,C#,Simple Injector,在静态构造函数中初始化简单的注入器容器合法吗 例如: using SimpleInjector; public static Bootstrapper { private readonly static Container container; static Bootstrapper() { Bootstrapper.container = new Container(); } } 应该是正常的,静态构造函数保证在第一次使用类型之前只调用一次

在静态构造函数中初始化简单的注入器容器合法吗

例如:

using SimpleInjector;

public static Bootstrapper
{
    private readonly static Container container;

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

应该是正常的,
静态
构造函数保证在第一次使用类型之前只调用一次,并且是线程安全的

从具体化

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

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


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

要获得更好的实践,请找到应用程序的入口点。假设它是静态void Main()
。在本例中,在此处创建容器的实例,并使用此容器创建启动对象(窗口、窗体等)


如果您正确地设计了DI,那么以后在应用程序中就不需要容器对象。只要确保在需要时通过构造函数将服务(在容器中注册的服务)注入到对象中即可


还有,看看。Mark在DI上有很多帖子,解释了为什么这是一种不好的做法。

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

我还想重复@WSriramSakthivel的警告:尽管在组合根目录中将
容器
声明为
public readonly static
字段,但尽可能防止从组合根目录之外访问此字段。从合成根外部使用它意味着应用

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


长话短说,虽然使用cctor可能很好,并提供了一些很好的保证,但我认为在大多数情况下,它只会成为阻碍。

将容器暴露为公共静态字段让我感到害怕。您是否使用容器作为服务定位器?为了技术性和清晰性,我将在我的问题中将其设置为私有的。如果您正确地设计了DI,您以后在应用程序中不应该需要容器对象。我同意,但我的问题不是关于设计原则。我只是好奇它在技术上是否合法(因为可能容器的初始化需要在调用程序集中的所有静态构造函数之后进行?我不知道技术细节,因此我的问题是:)容器不知道有关应用程序特定类及其静态构造函数的任何信息。因此,可以在静态构造函数中初始化它。不过,这不一定是最好的做法@除旋流器很好地解释了原因。