2013-09-06 3 views
9

Hallo Ich habe Probleme haben, Unity zu sagen, dass für eine Schnittstelle, wenn es mehrere Implementierungen hat, ich will es in verschiedenen Klassen injizieren.Hier ist was ich meine:Unity Register für eine Schnittstelle Mehrere Objekte und sagen Unity, wo sie injiziert werden

Lassen Sie uns sagen, ich habe eine Schnittstelle IProductCatalogService und zwei Implementierungen ProductCatalog : IProductCatalogService und ProductCatalogService : IProductCatalogService.

Wie würde ich mich über Unity zu sagen, dass für die Klasse A Ich möchte in meinem Konstruktor eine Instanz vom Typ ProductCatalog und B für die Klasse übergeben möchte ich eine Instanz von ProductCatalogService.

Ich verwende Unity in einem ASP.NET-Web-API-Projekt, und ich habe den Resolver in GLobalConfiguration festgelegt.

Für einfache 1 zu 1 Registrierungen funktioniert alles. Hier

ist, was ich versucht habe, aber es nicht zu funktionieren scheint:

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))); 
    } 
} 

Im DependencyServiceModel, From die Schnittstelle, To ist das Objekt Hexe ich instanziiert wollen und ForClasses sind der Typ für welches ich das Objekt To verwenden möchte.

Antwort

21

Im folgenden Beispiel haben Sie eine Schnittstelle zweimal implementiert und bei Bedarf in zwei verschiedene Client-Klassen injiziert, so wie Sie es wünschen. Der Trick besteht darin, benannte Registrierungen zu verwenden.

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) 
    { 

    } 
} 

Dies ist höchstwahrscheinlich, was Sie falsch machen:

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

Sie einen Namen Registrierung für Ihre konkrete Klasse erstellen. Stattdessen sollten Sie

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

haben Gibt es eine Möglichkeit, dies ohne Generika zu tun, ich keine genaue Art an der Stelle der Registrierung zur Verfügung stellen kann, wie Sie von meinem Code – aleczandru

+0

Natürlich sehen können, hat die Einheit Registrierungsverfahren in generisch und nicht generische Versionen. –

+0

Redigierte meinen Beitrag, um darauf hinzuweisen, was Sie falsch gemacht haben. –