2016-09-19 4 views
0

J'ai trois déclaration de classe comme ci-dessusest-il un moyen d'interposer le processus d'instanciation de autofac?

[Plug("hello")] 
public class Plug1 : IPlug{} 
[Plug("hello")] 
public class Plug2 : IPlug{} 
[Plug("world")] 
public class Plug3 : IPlug{} 

Quand j'utilise container.Resolve<IEnumerable<IPlug>>() pour résoudre, je reçois toutes les instances qui implémente l'interface IPlug,, je veux cependant obtenir le premier et le deuxième (ou par le monde, qui l'instance a été marquée par l'attribut Plug("hello")).

Y a-t-il un moyen de l'atteindre?

Je voudrais éviter d'utiliser

container.Resolve<IEnumerable<IPlug>>() 
     .Where(t => t.FirstAttribute<Plug>() != null 
        && t.FirstAttribute<Plug>().Id == "Hello") 

Je me sens toujours ce n'est pas la meilleure pratique en raison de la performance.

Répondre

1

Il existe de nombreuses façons de faire ce que vous voulez.

La meilleure façon serait d'enregistrer votre type que l'enregistrement du nom

builder.RegisterType<Plug1>().As<IPlug>().WithMetadata("plug", "hello"); 
builder.RegisterType<Plug2>().As<IPlug>().WithMetadata("plug", "hello"); 
builder.RegisterType<Plug3>().As<IPlug>().WithMetadata("plug", "world"); 

vous pouvez également utiliser l'attribut pour enregistrer ces types:

builder.RegisterType<Plug1>() 
     .As<IPlug>() 
     .WithMetadata("plug", typeof(Plug1).FirstAttribute<Plug>().?Id ?? "Default"); 

Ensuite, vous serez en mesure d'obtenir tous nommés enregistrement IPlug en utilisant un IEnumerable<Meta<IPlug>>:

container.Resolve<IEnumerable<Meta<IPlug>>>() 
     .Where(m => m.Metadata["plug"] as String == "hello") 
     .Select(m => m.Value); 

Si vous ne voulez pas filtrer lors de l'exécution, mais pendant la composition de la racine et IoC IEnumerable<IPlug> résoudrez toujours un filtre IEnumerable<IPlug> alors vous pouvez remplacer l'enregistrement IEnumerable<IPlug>:

builder.Register(c => c.Resolve<IEnumerable<Meta<IPlug>>>() 
         .Where(m => m.Metadata["plug"] as String == "hello") 
         .Select(m => m.Value)) 
     .As<IEnumerable<IPlug>>(); 
+0

merci. c'est un bon choix. – linus