2009-07-31 7 views
5

Ne peut pas obtenir ma tête autour du paramètre passant Autofac, le code suivant ne fonctionne pas:paramètre Autofac passage et autowiring

class Config { 
    public Config(IDictionary<string, string> conf) {} 
} 

class Consumer { 
    public Consumer(Config config) {} 
} 

void Main() 
{ 
    var builder = new Autofac.Builder.ContainerBuilder(); 
    builder.Register<Config>(); 
    builder.Register<Consumer>(); 
    using(var container = builder.Build()){ 
     IDictionary<string,string> parameters = new Dictionary<string,string>(); 
     var consumer = container.Resolve<Consumer>(Autofac.TypedParameter.From(parameters)); 
    } 
} 

qui jette:

DependencyResolutionException: The component 'UserQuery+Config' has no resolvable constructors. Unsuitable constructors included: 
Void .ctor(System.Collections.Generic.IDictionary`2[System.String,System.String]): parameter 'conf' of type 'System.Collections.Generic.IDictionary`2[System.String,System.String]' is not resolvable. 

mais le code suivant -t travail:

IDictionary<string,string> parameters = new Dictionary<string,string>(); 
var config = container.Resolve<Config>(Autofac.TypedParameter.From(parameters)); 
var consumer = container.Resolve<Consumer>(Autofac.TypedParameter.From(config)); 
+2

Votre question n'est pas très claire. Pour ceux d'entre nous qui ne sont pas utilisateurs d'autofac, pourriez-vous montrer les déclarations de p, config, TypedParameter.From et container.Resolve? Aussi, veuillez préciser de quelle manière cela "ne fonctionne pas" - compiler l'erreur de temps? Exception? –

+0

clarifié avec un exemple exécutable dans par exemple. LINQPad (référence Autofac.dll) –

Répondre

18

En répétant ici la réponse de la liste de diffusion Autofac:

Les paramètres passés à résoudre uniquement en rapport avec l'implémenteur directe de le service que vous résoudre, en passant si les paramètres de configuration pour la résolution appel gagné à la consommation ne fonctionne pas. La façon de contourner cela est de changer votre inscription des consommateurs à:

builder.Register((c, p) => new Consumer(c.Resolve<Config>(p))); 
+0

Je suppose que vous voulez dire: builder.Register ((c, p) => new Consommateur (c.Résolvez (p))); parce que cela fonctionne perfetct! Merci Nicolas! –

+3

+1 enfin quelqu'un qui sait autofac :-) – galaktor

+4

Par "enfin quelqu'un qui sait autofac" vous voulez dire l'auteur, ouais bien sûr :) – uriDium

0

Autofac tente évidemment résol Ve le paramètre de votre classe Config dans l'hypothèse que le dictionnaire lui-même est un type résolvable. Je ne connais pas la syntaxe autofac sur la façon de le faire. Mais vous devez probablement faire plus d'étapes lors de l'enregistrement du type de configuration, e. g. en lui donnant un délégué qui passe dans un nouveau dictionnaire.

+0

vous avez raison! mais le prochain problème survient, si j'inscris Config comme suit à la place: builder.Register ((c, p) => nouvelle Config (p.TypedAs >())); p est vide au moment de la résolution! –

+0

Hm. Peut-être que c'est parce que vous donnez un autofac à un délégué, mais le délégué n'a toujours pas le dictionnaire à l'exécution. Essayez en fait de fournir un nouveau dictionnaire dans votre délégué, quelque chose comme ça (attention, je ne connais pas encore les nominations exactes pour autofac): builder.Register ((c) => new Config (new Dictionary ())); – galaktor

+0

ne donnera-t-il pas toujours à Config un dictionnaire vide? malgré quels arguments sont passés au moment de la résolution? –

0

Malheureusement, les conteneurs IoC comme Autofac ne sont pas équipés d'un « s'il vous plaît lire mon module esprit ». Ce que vous essayez de faire est essentiellement de dire "Je sais qu'un des types impliqués ici a besoin d'un dictionnaire, et j'ai besoin d'un service de type Consommateur, pouvez-vous s'il vous plaît essayer de comprendre ce que je suis? prendre et juste faire la bonne chose ? ".

Si vous résolvez un service et spécifiez un paramètre, ce paramètre sera tenté d'être utilisé pour ce service particulier. Le conteneur n'essaiera pas de propager cette valeur de paramètre à aucune dépendance.

+0

bien sûr, mon premier essai était naïf, mais pas trop loin, si les paramètres avaient été foulés comme inscriptions il avait du travail? –

+0

Pourrait être, AutoFac devrait alors être en mesure de comprendre, mais vous auriez besoin de pré-enregistrer les paramètres en tant que services avec AutoFac. Personnellement, je ne recommande pas les services avec des paramètres constructeurs, c'est invariablement un service qui fuit car il fuit les détails d'implémentation dans le code qui l'utilise, ce qui rend plus difficile le remplacement ultérieur du service. Prenons comme exemple un service dans lequel vous lui passerez un nom de fichier de configuration, que se passe-t-il si vous décidez par la suite d'utiliser un service qui lit la configuration à partir d'une base de données? –

+0

oui je sais, ma solution n'est pas sur place mais la chose est, je veux que l'utilisateur puisse configurer quel type de service à utiliser. Mais ce service nécessite également différentes configurations, alors maintenant ces configurations de service sont passées en tant que IDictionary .. J'adorerais de meilleures solutions, mais cette chose d'usine est ma meilleure tentative jusqu'à présent .. –

Questions connexes