在静态构造函数中初始化容器
Initialize container in static constructor
在静态构造函数中初始化简单注入器容器是否合法?
示例:
using SimpleInjector;
public static Bootstrapper
{
private readonly static Container container;
static Bootstrapper()
{
Bootstrapper.container = new Container();
}
}
应该没问题,static
构造函数保证在类型首次使用之前只调用一次并且是线程安全的。
来自规范
Static constructors are not inherited, and cannot be called directly.
The static constructor for a closed class type executes at most once in a given application domain.
The execution of a static constructor is triggered by the first of the following events to occur within an application domain:
• An instance of the class type is created.
• Any of the static members of the class type are referenced.
根据我的经验,在大多数情况下您应该尽量避免使用静态实例。想象一下,容器 的生命周期与应用程序的生命周期相匹配。换句话说,如果您将 container 设置为静态,它将保持活动状态直到应用程序关闭。
要获得更好的做法,请找到您的应用程序的入口点。假设它是 static void Main()。在这种情况下,在这里创建一个容器的实例,并使用这个容器创建启动对象(Windows、Forms 等)。
如果您正确设计了 DI,您以后在应用程序中应该不需要 container 对象。只需确保在需要时通过构造函数将服务(已注册到 容器)注入到对象中即可。
此外,请查看 Service Locator violates SOLID by Mark Seemann。 Mark 有很多关于 DI 的帖子,并解释了为什么这是一种不好的做法。
正如@NedStoyanov 所说,静态构造函数可以保证唯一性,因此这可能是有益的。然而,静态构造函数的缺点是它们通常更难调试,并且从 cctor 主体抛出的任何异常都包含在 InitializationException 中,这使得更难看到实际问题。
我还想重复@WSriramSakthivel 的警告:尽管在组合根中将 Container
声明为 public readonly static
字段,但请防止从 外部 [=22= 访问此字段] 组合根,只要有可能。从组合根外部使用它意味着应用 Service Locator anti-pattern.
请注意,使用 cctor 初始化容器也有缺点。在集成测试和 运行 一些使用容器构建对象图的集成测试中验证容器时,您通常希望让每个测试都有自己的容器实例,其配置略有不同。这是你在使用 cctor 时无法工作的东西。
长话短说,虽然使用 cctor 可能很好并且提供了一些很好的保证,但我认为在大多数情况下,它只会成为阻碍。
在静态构造函数中初始化简单注入器容器是否合法?
示例:
using SimpleInjector;
public static Bootstrapper
{
private readonly static Container container;
static Bootstrapper()
{
Bootstrapper.container = new Container();
}
}
应该没问题,static
构造函数保证在类型首次使用之前只调用一次并且是线程安全的。
来自规范
Static constructors are not inherited, and cannot be called directly. The static constructor for a closed class type executes at most once in a given application domain.
The execution of a static constructor is triggered by the first of the following events to occur within an application domain:
• An instance of the class type is created.
• Any of the static members of the class type are referenced.
根据我的经验,在大多数情况下您应该尽量避免使用静态实例。想象一下,容器 的生命周期与应用程序的生命周期相匹配。换句话说,如果您将 container 设置为静态,它将保持活动状态直到应用程序关闭。
要获得更好的做法,请找到您的应用程序的入口点。假设它是 static void Main()。在这种情况下,在这里创建一个容器的实例,并使用这个容器创建启动对象(Windows、Forms 等)。
如果您正确设计了 DI,您以后在应用程序中应该不需要 container 对象。只需确保在需要时通过构造函数将服务(已注册到 容器)注入到对象中即可。
此外,请查看 Service Locator violates SOLID by Mark Seemann。 Mark 有很多关于 DI 的帖子,并解释了为什么这是一种不好的做法。
正如@NedStoyanov 所说,静态构造函数可以保证唯一性,因此这可能是有益的。然而,静态构造函数的缺点是它们通常更难调试,并且从 cctor 主体抛出的任何异常都包含在 InitializationException 中,这使得更难看到实际问题。
我还想重复@WSriramSakthivel 的警告:尽管在组合根中将 Container
声明为 public readonly static
字段,但请防止从 外部 [=22= 访问此字段] 组合根,只要有可能。从组合根外部使用它意味着应用 Service Locator anti-pattern.
请注意,使用 cctor 初始化容器也有缺点。在集成测试和 运行 一些使用容器构建对象图的集成测试中验证容器时,您通常希望让每个测试都有自己的容器实例,其配置略有不同。这是你在使用 cctor 时无法工作的东西。
长话短说,虽然使用 cctor 可能很好并且提供了一些很好的保证,但我认为在大多数情况下,它只会成为阻碍。