0

I am trying to implement DI on my .Net application. I have 3 API classes in my Data Access layer. I have to use any one of them at a time. I am trying to put conditional unity resolution but not sure how to accomplish it. Please some body help me with sample code how to manage my 3 injected classes conditionally.

Currently I have just registered my classes in following way-

            IUnityContainer _container = new UnityContainer(); 
            _container.RegisterType(typeof(IPolicyAdminApi), typeof(SomeApiclass1)); 
            _container.RegisterType(typeof(IPolicyAdminApi), typeof(SomeApiclass2)); 
            _container.RegisterType(typeof(IPolicyAdminApi), typeof(SomeApiclass3)); 
            IPolicyAdminApi policyAdmin = _container.Resolve<IPolicyAdminApi>(); 
            return policyAdmin;
1
  • I've posted a suggestion, but you should really be asking yourself why you have a single service being implemented in 3 ways - are you sure you shouldn't have 3 separate services (i.e. 3 separate interfaces)...? Commented Apr 3, 2017 at 10:58

2 Answers 2

1

Unity supports named registrations to allow for this disambiguation, so you can write your registration code like this:

IUnityContainer _container = new UnityContainer(); 
_container.RegisterType("A", typeof(IPolicyAdminApi), typeof(SomeApiclass1)); 
_container.RegisterType("B", typeof(IPolicyAdminApi), typeof(SomeApiclass2)); 
_container.RegisterType("C", typeof(IPolicyAdminApi), typeof(SomeApiclass3)); 
IPolicyAdminApi policyAdmin = _container.Resolve<IPolicyAdminApi>("A"); 
return policyAdmin;

You can specify which registration you require using the Unity Dependency attribute:

public SomeConstructor([Dependency("A")] IPolicyAdminApi api)
{
}
Sign up to request clarification or add additional context in comments.

3 Comments

This seems fantastic idea. It helps . But i want to resolve this dependency at runtime. Currently we are configuring it to resolve "A". Do you mean we can add if condition here to put some condition on all of 3 classes.
@PratikBompilwar You probably want to build an IPolicyAdminApiFactory in that case - look up the Factory pattern. It's a bit unclear what you are actually after though.
Thanks @RB for the help. Specifying names and then putting it in if else condition works for me.
1

As suggested in another answer, the solution with UnityIoC is Named Registration, combined with a factory. You could do a typical factory pattern, but what I've been doing, to full-on dependency injection, is inject the factory, as a function :

In the registration :

// Register the named instances.
_container.RegisterType<IPolicyAdminApi, SomeApiclass1>("Name1"); 
_container.RegisterType<IPolicyAdminApi, SomeApiclass2>("Name2"); 
_container.RegisterType<IPolicyAdminApi, SomeApiclass3>("Name3"); 

// Register the factory.
_container.RegisterType<Func<string, IPolicyAdminApi>>(
            new InjectionFactory(c =>
                new Func<string, IPolicyAdminApi>(
                    namedInstance => c.Resolve<IPolicyAdminApi>(namedInstance))));

In the class

class ImUsingTheRegistration
{
    private Func<string, IPolicyAdminApi> iPolicyAdminApiFactory;

    public ImUsingTheRegistration(Func<string, IPolicyAdminApi> iPolicyAdminApiFactory)
    {
        this.iPolicyAdminApiFactory = iPolicyAdminApiFactory;
    }

    public void ImAtRunTime()
    {
        string namedInstance = "Name" + Datetime.Now.ToString().Right(1);

        IPolicyAdminApi instance = iPolicyAdminApiFactory(namedInstance);
    }
}

Notes: I'm using generic registration, but it would work with the other pattern too. Also, that would fail cause there are no registration for 4, 5, ... 0, but you get the idea.

1 Comment

Thanks @Tipx. Naming instances helps me in my goal.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.