2009-12-28 2 views
4

je suivant extrait:Unité: Spécifiez la dépendance nom lors de la configuration

static void Main(string[] args) { 
    var container = new UnityContainer(); 
    container.RegisterType<IConnection, SerialPortConnection>("SerialConnection"); 
    container.RegisterType<IConnection, ParallelPortConnection>("ParallelConnection"); 
    container.RegisterType<Device>("ParallelDevice"); 
    container.RegisterType<Device>("SerialDevice"); 
} 

Je veux enregistrer le type Device sous deux noms différents, de sorte que selon le nom demandé Device instance serait initialisé avec Connection approprié. Voici une façon de résoudre cela, juste pour la démonstration:

public class ParallelDevice : Device { 
    public ParallelDevice([Dependency("ParallelConnection")] IConnection connection) : base(connection) {} 
} 
public class SerialDevice : Device { 
    public SerialDevice([Dependency("ParallelConnection")] IConnection connection) : base(connection) {} 
} 

// and register with 
container.RegisterType<Device, ParallelDevice>("ParallelDevice"); 
container.RegisterType<Device, SerialDevice>("SerialDevice"); 

Y a-t-il une meilleure façon de le faire? Quelque chose comme:

container.RegisterType<Device>("ParallelDevice").UseDependencyNames("ParallelConnection"); 

Répondre

2

Vous pouvez le faire comme ceci:

var container = new UnityContainer() 
    .RegisterType<IConnection, SerialConnection>("SerialConnection") 
    .RegisterType<Device, SerialDevice>(new InjectionConstructor(
     new ResolvedParameter<IConnection>("SerialConnection"))); 

ou comme ceci:

container 
    .Configure<InjectedMembers>() 
    .ConfigureInjectionFor<ParallelDevice>(new InjectionConstructor(
     new ResolvedParameter<IConnection>("ParallelConnection"))); 

This article a plus d'exemples, ainsi que quelques extensions pour l'unité qui vous permettent de écrire des tests comme celui-ci:

[Test] 
public void Should_inject_named_instance_of_encryption_provider() 
{ 
    var service = container.Resolve<MyService>(); 

    AssertNamedInstanceWasResolved<IEncryptionProvider>("MyEncryptionProvider"); 
} 
4

Vous devriez vous efforcer de garder votre code exempt de spécificités DI Container. Dans ce cas, vous pouvez simplement définir vos appareils sans faire référence à Unity. Voici le SerialDevice comme exemple, mais la classe ParallelDevice est tout à fait similaire:

public class SerialDevice : Device 
{ 
    public SerialDevice(IConnection connection) 
     : base(connection) { } 
} 

Vous pouvez configurer votre conteneur comme ceci:

container.RegisterType<IConnection, SerialPortConnection>("SerialConnection"); 
container.RegisterType<IConnection, ParallelPortConnection>("ParallelConnection"); 
container.RegisterType<Device, SerialDevice>("SerialDevice", 
    new InjectionConstructor(new ResolvedParameter<IConnection>("SerialConnection"))); 
container.RegisterType<Device, ParallelDevice>("ParallelDevice", 
    new InjectionConstructor(new ResolvedParameter<IConnection>("ParallelConnection"))); 

Cela vous permettra de résoudre les deux objets de l'appareil comme celui-ci:

var serialDevice = container.Resolve<Device>("SerialDevice"); 
var parallelDevice = container.Resolve<Device>("ParallelDevice"); 
Questions connexes