【问题标题】:Prototype objects and "Per Graph" DI Lifecycle原型对象和“每图”DI 生命周期
【发布时间】:2020-11-17 17:25:37
【问题描述】:

我有一个Credentials 类,应该通过依赖注入作为实例提供给所有需要它的构造函数。目前,我已经通过将类的单个实例注册到我的 DI 容器中解决了这个问题,并且具有单例生命周期。这确保了每次 DI 调用,所有对象都收到相同的凭据。这可行,但有点尴尬,因为 Credentials 单例的属性将在每次显式 DI 调用之间发生变化。这意味着每个接收者构造函数必须在更改之前立即从 Credentials 实例中“获取并保存”凭据属性。

如果我可以让 DI 容器创建一个新的 Credentials 实例,基于原型对象(是的,GOF“原型”模式)的每个图形或每个调用,这会变得更好。我正在使用 Simple Injector,所以我的第一个解决方案如下所示:

public static Credentials creds; //Implements ICloneable

//....

var prototypeTransientLifestyle = Lifestyle.CreateCustom(
    name: "Prototype Transient",
    // instanceCreator is of type Func<object>
    lifestyleApplierFactory: instanceCreator =>
    {
        return () => creds.Clone();
    });

我认为这是可行的,但即便如此,它也有两个弱点。首先,它只能应用于我的Credentials 类。我希望它一般可重复使用。其次,它在单个显式 DI 调用中可能创建许多克隆。我希望它具有“每图”生命周期,以便它只创建一次克隆并在该 DI 调用的其余部分重新使用它。

关于如何进行的任何想法?

顺便说一句,我知道“按图”生命周期存在与惰性求值相关的问题。我没有任何懒惰的评估,所以这不是问题。

更新

我认为我的问题有部分解决方案。为了以通用方式实现原型克隆,我可以这样做:

container.Register<Credentials>(() => (Credentials)creds.Clone());

现在我仍然想要“按图”行为。进一步阅读建议我需要使用简单的注射器Scope。显然,这要求我有一个调用 DI 容器的中心位置,以便我可以显式创建范围。我的代码确实非常适合这种情况,但我仍然想知道是否有另一种方法可以实现不需要显式创建范围的“每个图”。

【问题讨论】:

    标签: c# .net-core design-patterns dependency-injection simple-injector


    【解决方案1】:

    正如文档中的noted,Simple Injector 没有“按图”生活方式的概念。相反,Scoped 生活方式提供了通常足够接近的行为。

    显然,这要求我有一个调用 DI 容器的中心位置,以便我可以显式创建范围。

    没错。这个中心位置称为Composition Root,每个应用程序都会拥有它。

    我仍然想知道是否有另一种方法来实现“每个图”,它不需要显式创建范围。

    Simple Injector GitHub 存储库包含 a code example that demonstrates the Per Graph lifestyle,但我的建议是坚持使用内置构造,​​即 ScopedLifestyle。

    【讨论】:

      猜你喜欢
      • 2010-12-06
      • 1970-01-01
      • 2011-04-28
      • 1970-01-01
      • 1970-01-01
      • 2011-02-19
      • 1970-01-01
      • 2011-03-16
      相关资源
      最近更新 更多