2011-01-23 1 views
6

Par exemple, j'ai enregistré la classe C1 avec un paramètre dans le constructeur de type System.Type. J'ai une autre classe (C2) avec paramètre injecté de type C1. Et je veux recevoir typeof(C2) automatiquement dans le constructeur C1. Est-ce possible d'une certaine façon?Est-il possible d'obtenir le type de conteneur dans AutoFac

code Exemple:

public class C1 
{ 
    public C1(Type type) {} 

    // ... 
} 

public class C2 
{ 
    public C2(C1 c1) {} 

    // ... 
} 

// Registration 
containerBuilder.Register(???); 
containerBuilder.Register<C2>(); 

Répondre

7

Cela devrait le faire:

builder.RegisterType<C1>(); 
builder.RegisterType<C2>(); 
builder.RegisterModule(new ExposeRequestorTypeModule()); 

Où:

class ExposeRequestorTypeModule : Autofac.Module 
{ 
    Parameter _exposeRequestorTypeParameter = new ResolvedParameter(
     (pi, c) => c.IsRegistered(pi.ParameterType), 
     (pi, c) => c.Resolve(
      pi.ParameterType, 
      TypedParameter.From(pi.Member.DeclaringType))); 

    protected override void AttachToComponentRegistration(
      IComponentRegistry registry, 
      IComponentRegistration registration) 
    { 
     registration.Preparing += (s, e) => { 
      e.Parameters = new[] { _exposeRequestorTypeParameter } 
       .Concat(e.Parameters); 
     }; 
    } 
} 

Tout composant qui prend un paramètre System.Type va obtenir le type du demandeur passé (le cas échéant). Une amélioration possible pourrait être d'utiliser un NamedParameter plutôt que TypedParameter pour restreindre les paramètres Type qui seront appariés uniquement à ceux avec un certain nom.

S'il vous plaît laissez-moi savoir si cela fonctionne, d'autres ont posé sur la même tâche générale et ce serait bien de partager avec eux.

+0

Non, malheureusement, cela ne fonctionne pas. LimitType est le type de composant lui-même (C1 dans ce cas) – oryol

+0

Ah - doh! - Merci pour ça. Je vais réfléchir à des alternatives et les poster ici si j'en trouve. –

+0

Le principal problème est dans AutowiringParameter. Il invoque toujours la résolution pour les enfants sans paramètres (avec enumerable vide). J'ai créé un paramètre similaire et l'ai enregistré dans registration.ActivatorData.ConfiguredParameters (où ActivatorData est ReflectionActivatorData) avec la valeur: registration.ActivatorData.ImplementationType. Mais cela ne fonctionne que pour c.Resolve explicite (et avec l'injection de C1 lui-même j'ai obtenu 'Non des constructeurs trouvés ...' pour C1) .. – oryol

Questions connexes