tags:

views:

39

answers:

2

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 constructor 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.

A: 

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();
Peter Lillevold
We have a Web application in which Common is HttpRequestScoped. I am working on a windows service / console admin app that takes advantage of the existing code, so I need Common setup when I run a specific task and then cleared.
Thad
If so, I would probably operate with three different registration modules, one that handles registrations common to both applications, and one module for each application handling registrations that differs.
Peter Lillevold
SomeClass (InstancePerDependency) and OtherClass (InstancePerDependency) are registered in the Main assembly. Common is registered in each application. When its InstancePerDependency i get a new one each time, when InstancePerLifetime I always get the same one everytime. So I must be missing something related to the lifetime.
Thad
A: 

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