使用Lazy<T>
属性缓存,在使用支持字段访问属性或没有支持字段之间是否存在任何行为差异?也许任何表演都会出现?
下面的示例代码是在内部属性中缓存Autofac IoC container。该代码仅用于初始化一次。它是否遵循正确的IoC / DI原则不是问题。
示例1:
internal static ILifetimeScope Bootstrap = new Lazy<ILifetimeScope>(InitializeContainer, LazyThreadSafetyMode.ExecutionAndPublication).Value;
private static ILifetimeScope InitializeContainer()
{
ContainerBuilder builder = new ContainerBuilder();
//Registration logic...
return builder.Build();
}
示例2:
private static readonly Lazy<ILifetimeScope> _container = new Lazy<ILifetimeScope>(InitializeContainer, LazyThreadSafetyMode.ExecutionAndPublication);
internal static ILifetimeScope Container => _container.Value;
private static ILifetimeScope InitializeContainer()
{
ContainerBuilder builder = new ContainerBuilder();
//Registration logic...
return builder.Build();
}
修改1 我最感兴趣的是拥有容器的缓存值,因此每次访问该属性时都不会初始化它。我不在乎初始化是否延期。
答案 0 :(得分:2)
IMO在第一个示例中调用该行上的.Value使得Lazy几乎无用,因为它是在下一次实例化惰性对象时实例化容器,所以如果创建该对象不会延迟到以后的时间。
所以,如果你需要推迟创建对象,那么我认为第二个例子更好,因为容器在调用Container的第一个时刻之前不会被初始化。
另一个例子是一个没有.Value的字段,所以它与第二个例子相同,但是你必须在任何想要使用它的地方调用.Value,这会让它有点不舒服。
internal static Lazy<ILifetimeScope> Bootstrap = new Lazy<ILifestimeScope>(InitializeContainer, LazyThreadSafetyMode.ExecutionAndPublication);
所以,如果我在你的位置,我会去第二个例子,既可以调用,也可以使Lazy加载很有用,但请记住,第一次调用它会初始化容器,所以第一次使用它将花费比第一个例子更多的时间来完成动作