【问题标题】:Autofac not passing same instance to resolved arguments in constructorAutofac没有将相同的实例传递给构造函数中的解析参数
【发布时间】:2010-07-27 14:36:50
【问题描述】:

我有以下设置

public class CommonClass : ICommonClass
{
}

public class SomeClass : ISomeClass
{
   public SomeClass(ICommonClass common, IOtherClass otherClass) {}
}

public class OtherClass : IOtherClass
{
  public OtherClass(ICommonClass common) {}
}

//Registration
builder.RegisterType<CommonClass>().As<ICommonClass>().InstancePerDependency();
builder.RegisterType<SomeClass>().As<ISomeClass>().InstancePerDependency();
builder.RegisterType<OtherClass>().As<IOtherClass>().InstancePerDependency();

我希望每个构造函数中的 common 参数是相同的实例,但要在 SomeClass 被解析时创建 ICommon 的新实例。我怎么能让这个时间发生。我试图将它们注册为 InstancePerLifetimeScope,但它的行为与 SingleInstance 相同。

【问题讨论】:

标签: autofac


【解决方案1】:

InstancePerDependency 是当您需要每个依赖项的新实例时要走的路。现在为不同的依赖类设置不同的生命周期是很棘手的,而且感觉不对。如果您能详细说明为什么需要这种行为,也许可以找到更好的方法。

也就是说,要完成您的要求(尽管我不喜欢它;),您可以使用“实例持有者”。我的想法是,对于常规依赖项,新的公共实例将照常提供。但是对于特殊情况SomeClass,公共实例是从这个始终服务于同一个实例的持有者类中获取的:

public class CommonHolder
{
    public ICommonClass Instance {get;private set;}
    public CommonHolder(ICommonClass commonInstance)
    {
        Instance = commonInstance;
    }
}

然后是注册设置:

builder.RegisterType<CommonHolder>().SingleInstance();
builder.RegisterType<OtherClass>().As<IOtherClass>().InstancePerDependency();
builder.RegisterType<CommonClass>().As<ICommonClass>().InstancePerDependency();

builder.RegisterType<SomeClass>().InstancePerDependency();
builder.Register(c =>
    c.Resolve<SomeClass>(TypedParameter.From(c.Resolve<CommonHolder>().Instance)))
    .As<ISomeClass>().InstancePerDependency();

【讨论】:

  • 我们有一个 Web 应用程序,其中 Common 是 HttpRequestScoped。我正在开发一个利用现有代码的 Windows 服务/控制台管理应用程序,因此当我运行特定任务然后清除时我需要通用设置。
  • 如果是这样,我可能会使用三个不同的注册模块,一个处理两个应用程序共有的注册,一个模块用于每个应用程序处理不同的注册。
  • SomeClass (InstancePerDependency) 和 OtherClass (InstancePerDependency) 在 Main 程序集中注册。共同在每个应用程序中注册。当它的 InstancePerDependency 我每次都得到一个新的时,当 InstancePerLifetime 我总是每次都得到相同的。所以我一定错过了一些与生命有关的东西。
【解决方案2】:

您可以创建一个单独的 ICommonClass 命名注册,并仅在解析 SomeClass 时使用它:

// Existing registration
builder.RegisterType<CommonClass>().As<ICommonClass>().InstancePerDependency();

// One-off registration
builder
    .RegisterType<CommonClass>()
    .As<ICommonClass>()
    .InstancePerLifetimeScope()
    .Named<ICommonClass>("OneOffCommonClass");

// New registrations of dependents
builder.RegisterType<OtherClass>().As<IOtherClass>().InstancePerDependency();

builder
    .Register(c => new SomeClass(
        c.Resolve<ICommonClass>("OneOffCommonClass"),
        c.Resolve<IOtherClass>()))
    .As<ISomeClass>()
    .InstancePerDependency();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-08-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-27
    相关资源
    最近更新 更多