Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
503 views
in Technique[技术] by (71.8m points)

c# - Unity Register For One Interface Multiple Object and Tell Unity Where to Inject them

Hi I have been having trouble trying to tell Unity that for an Interface if it has multiple implementations , I want it to inject them in different classes.Here is what I mean:

Let's say I have an interface IProductCatalogService and two implementations ProductCatalog : IProductCatalogService and ProductCatalogService : IProductCatalogService.

How would I go about telling Unity that for Class A I want in my constructor passed an instance of type ProductCatalog and for Class B I want an instance of ProductCatalogService.

I am using Unity in an ASP.NET Web API project and I have set the resolver in the GLobalConfiguration.

For simple 1 to 1 registrations everything works.

Here is what I have tried but it does not seem to work:

public class DependencyServiceModel
{
    public Type From { get; set; }
    public Type To { get; set; }
    public IEnumerable<Type> ForClasses { get; set; }
}

public void RegisterTypeForSpecificClasses(DependencyServiceModel dependencyService)
{
    foreach (var forClass in dependencyService.ForClasses)
    {
        string uniquename = Guid.NewGuid().ToString();

        Container.RegisterType(dependencyService.From, 
            dependencyService.To, uniquename);

        Container.RegisterType(forClass, uniquename, 
            new InjectionConstructor(
                new ResolvedParameter(dependencyService.To)));
    }
}

In the DependencyServiceModel, From is the interface, To is the object to witch I want to instantiate and ForClasses are the Type for which I want to use the To Object.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

In the example below you have an interface implemented twice and injected on demand into two different client classes, just as you request. The trick is to use named registrations.

class Program
{
    static void Main(string[] args)
    {
        IUnityContainer container = new UnityContainer();
        container.RegisterType<IFoo, Foo1>("Foo1");
        container.RegisterType<IFoo, Foo2>("Foo2");

        container.RegisterType<Client1>(new InjectionConstructor(new ResolvedParameter<IFoo>("Foo1")));
        container.RegisterType<Client2>(new InjectionConstructor(new ResolvedParameter<IFoo>("Foo2")));

        Client1 client1 = container.Resolve<Client1>();
        Client2 client2 = container.Resolve<Client2>();
    }
}

public interface IFoo
{

}

public class Foo1 :IFoo
{

}

public class Foo2 : IFoo
{

}

public class Client1
{
    public Client1(IFoo foo)
    {

    }
}

public class Client2
{
    public Client2(IFoo foo)
    {

    }
}

This is most probably what you do wrong:

 Container.RegisterType(forClass, uniquename, 
        new InjectionConstructor(
            new ResolvedParameter(dependencyService.To)));

You create a named registration for your concrete class. Instead you should have

 Container.RegisterType(forClass, null, 
        new InjectionConstructor(
            new ResolvedParameter(dependencyService.To, uniquename)));

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...