开发者

Autofac not passing same instance to resolved arguments in constructor

I have the following setup

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();

I would like the common argument in each c开发者_如何学编程onstructor to be the same instance, but for it to create new instance of ICommon when SomeClass is resolved. How can I get this time happen. I attempted to register them as InstancePerLifetimeScope but it acted the same as SingleInstance.


InstancePerDependency is the way to go when you need new instances for every dependency. Now to have varying lifetimes for different dependent classes is tricky and doesn't feel right. If you can elaborate on why you need this behavior perhaps a better way could be found.

That said, to accomplish what you ask (though I do not like it ;), you could utilize a "instance holder". My thought is that for regular dependencies, new common instances will be served as usual. But for the special case SomeClass, the common instance is fetched from this holder class that always serves the same instance:

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

and then the registration setup:

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();


You could create a separate named registration of ICommonClass and use that only when resolving 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();
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜