9

Je sais que certains frameworks DI supportent ceci (par exemple Ninject), mais je veux spécifiquement savoir si c'est possible avec Autofac. Je souhaite pouvoir demander un conteneur Autofac pour une classe concrète et récupérer une instance avec toutes les dépendances constructeurs appropriées injectées, sans jamais enregistrer cette classe concrète. à savoir, si je ne lie explicitement, alors automatiquement lier la classe concrète elle-même, comme si je l'avais appelé builder.Register<MyClass>();Est-ce que Auto Autofac peut effectuer une reliure automatique?

Un bon exemple quand cela serait utile est ViewModels. Dans MVVM, la superposition est telle que seule la vue dépend du ViewModel, et cela par une saisie lâche, et vous ne testez pas la View de toutes façons. Il n'est donc pas nécessaire de se moquer du ViewModel pour les tests - et il n'y a donc aucune raison d'avoir une interface pour chaque ViewModel. Donc, dans ce cas, le schéma DI habituel de "enregistrer cette interface pour résoudre cette classe" est une complexité inutile. Auto-contraignant explicite, comme builder.Register<MyClass>();, se sent aussi comme une étape inutile lorsqu'il s'agit de quelque chose d'aussi simple que d'une classe concrète.

Je suis au courant de la reflection-based registration example dans les docs Autofac, mais ce n'est pas à mon goût non plus. Je ne veux pas la complexité (et la lenteur) de l'enregistrement de toutes les classes possibles à l'avance; Je veux que le cadre me donne ce dont j'ai besoin quand j'en ai besoin. Convention sur la configuration, et tout ça. Y at-il un moyen de configurer Autofac pour qu'il puisse dire "Oh, c'est un type concret, et personne ne l'a encore enregistré, alors je vais agir comme s'il avait été enregistré avec les paramètres par défaut"?

Répondre

12
builder.RegisterTypesMatching(type => type.IsClass) 

Si vous look at the source vous verrez que RegisterTypesMatching (et RegisterTypesFromAssembly) ne fait rien RÉFLEXION. Dans ce cas, Autofac enregistre une règle qui accepte un type ou non. Dans mon exemple ci-dessus j'accepte tout type qui est une classe. Dans le cas de RegisterTypesFromAssembly, Autofac enregistre une règle qui dit "si le type que vous essayez de résoudre a Assembly == l'assembly spécifié, alors je vous donnerai une instance".

Alors:

  1. pas de réflexion de type se fait au moment de registre
  2. tout type correspondant aux critères sera résolu

Par rapport à enregistrer les types de béton directement, cela Avoir un succès au moment de la résolution puisque Autofac devra comprendre par exemple exigences du constructeur. Cela dit, si vous allez avec la portée d'instance par défaut, qui est singleton, vous ne prenez le hit que la première fois que vous résolvez ce type. La prochaine fois, il utilisera l'instance singleton déjà créée.

Mise à jour: dans Autofac 2 il existe une meilleure façon de rendre le conteneur capable de résoudre n'importe quoi. Cela implique the AnyConcreteTypeNotAlreadyRegistered registration source.

+0

Sweet - ressemble exactement à ce que je cherchais. Merci! –

2

Qu'en est:

builder.RegisterTypesFromAssembly(Assembly.GetExecutingAssembly()); 

aucune réflexion se fait, comme Peter Lillevold points out.

+1

J'ai supprimé mes commentaires précédents parce que vous aviez raison (comme vous l'avez précisé dans votre édition): RegisterTypesFromAssembly ne fait pas de réflexion de masse comme son nom l'indique. C'est juste une famille de fonctions sténographiques autour de RegisterTypesMatching, et fait exactement ce que je recherche, mais avec un contrôle beaucoup plus fin, ce qui est plutôt gentil. Mes excuses pour avoir mal compris votre réponse la première fois. –

+0

Le lien que vous avez donné est cassé ... – Guillaume

+1

s'il vous plaît pardonnez-moi, mais cette réponse est de 3 ans: P d'ailleurs, beaucoup de choses se sont passées à autofac depuis lors, je ne pense pas que cela soit pertinent plus longtemps .. –