Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Conditionally resolve named implementation in Unity

Unity allows you to name different implementations of the same interface and then resolve them by name:

var container = new UnityContainer();

// register
container.Register<IFish, OneFish>("One");
container.Register<IFish, TwoFish>("Two");

// resolve
var twoFish = container.Resolve("Two");

Now assume I have a class that depends on IFish and implements ITank:

class Tank : ITank
{
   public Tank(IFish fish) {...}
}

How can I resolve ITank and specify which implementation of IFish to get?

This doesn't work:

container.Register<ITank, Tank>();

var tank = container.Resolve<ITank>("One");

This works:

var fish = container.Resolve<IFish>("One");

var tank = container.Resolve<Tank>(new DependencyOverride(typeof(IFish), fish);

but it only handles simple cases (such as in this example) not the general case where there may be many implementations named "One". What I want is to be able to tell to Unity:

"When resolving use implementations named "One", if no such implementation is register fall back to the unnamed implementation"

Is there a custom resolver that can be plugged into Unity with this behavior?

like image 617
Eli Algranti Avatar asked Oct 04 '13 00:10

Eli Algranti


Video Answer


1 Answers

You could you the InjectionFactory of Unity to inject a named instance.

var container = new UnityContainer();

// register
container.Register<IFish, OneFish>("One");
container.Register<IFish, TwoFish>("Two");

container.RegisterType<ITank,Tank>(new InjectionFactory(c=>c.Resolve<IFish>("One")));

If you now resolve an instance of type Tank, an instance of OneFish is injected to your Tank.

To handle your case that you want to inject a default implemenation of IFish you can change InjectionFactory to the following

new InjectionFactory(c=>{
  if (c.IsRegistered<IFish>("One")) {
    c.Resolve<IFish>("One");
  }
  else {
    c.Resolve<IFish>("Two");
  }
})
like image 87
Jehof Avatar answered Oct 11 '22 09:10

Jehof