开发者

Autofac not passing same instance to resolved arguments in constructor

开发者 https://www.devze.com 2023-01-09 06:09 出处:网络
I have the following setup public class CommonClass : ICommonClass { } public class SomeClass : ISomeClass

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

精彩评论

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

关注公众号