2010-12-02 26 views
2

Est-il possible de faire en sorte que l'unité essaie tous les constructeurs définis en commençant par celui qui a le plus d'arguments jusqu'au plus petit (le constructeur par défaut)?Unité et constructeurs

Modifier

Ce que je veux dire:

foreach (var constructor in concrete.GetConstructorsOrderByParameterCount()) 
{ 
    if(CanFulfilDependencies(constructor)) 
    { 
     UseConstructor(constructor); 
     break; 
    } 
} 

Je ne veux pas l'unité d'essayer seul le constructeur avec la plupart des paramètres. Je veux qu'il continue à essayer jusqu'à ce qu'il trouve un constructeur approprié. Si Unity ne fournit pas ce comportement par défaut, est-il possible de créer une extension ou quelque chose pour pouvoir le faire?

Edit 2

Je suis une classe avec deux constructeurs:

public class MyConcrete : ISomeInterface 
{ 
    public MyConcrete (IDepend1 dep, IDepend2 dep2) 
    {} 

    public MyConcrete(IDepend1 dep) 
    {} 
} 

La classe existe dans une bibliothèque qui est utilisée par plusieurs projets. Dans ce projet, je veux utiliser deuxième constructeur. Mais l'unité s'arrête car elle ne peut pas remplir les dépendances du premier constructeur. Et je ne veux pas vouloir changer la classe depuis le premier constructeur est utilisé par DI dans d'autres projets.

D'où la nécessité pour Unity d'essayer de résoudre tous les constructeurs.

+1

Que voulez-vous dire par "essayer"? –

+0

Encore une fois ... vous dites "approprié" ... s'il vous plaît fournir un code où ce problème fait surface, car il peut rendre les choses plus claires. Les constructeurs ne devraient pas dépendre en général des entités externes en dehors de ce qui est passé, ne devraient pas jeter des exceptions, etc ... Edited ma réponse cependant ... –

+0

a mis à jour la question. – jgauffin

Répondre

3

Unity choisira le constructeur ayant le plus de paramètres sauf si vous marquez explicitement un constructeur avec l'attribut [InjectionConstructor] qui définirait alors le constructeur à utiliser pour Unity.

Lorsque vous définissez un constructeur approprié; Cela dépend un peu de l'environnement. Si, par exemple, vous voulez toujours garantir qu'un certain constructeur est utilisé lors de l'utilisation de Unity, utilisez l'attribut mentionné précédemment, sinon appelez explicitement le constructeur que vous souhaitez utiliser.

Quel serait le but de Unity "essayant" tous les constructeurs? Son but est de fournir une instance d'un type de manière découplée. Pourquoi passerait-il en revue les constructeurs si un constructeur créait une instance du type?

EDIT:

Vous pouvez permettre au constructeur avec le plus params à utiliser dans le projet qui ne dispose pas d'une référence à ce type dans son conteneur en utilisant un child container. Cela ne forcera pas l'utilisation du constructeur avec un seul param mais cela permettra au constructeur avec 2 params de travailler sur les projets maintenant.

Vous pouvez également passer à l'utilisation du constructeur unique à travers le tableau et forcer l'autre interface via une autre forme de DI (Injection de propriété), pas Constructor Injection ... donc la base est applicable à travers les projets qui feraient plus sens.

+0

Je voulais juste clarifier quelque chose: l'attribut est de dire au conteneur quel constructeur appeler. Vous pouvez également utiliser l'API ou le fichier de configuration. L'un ou l'autre est préférable à l'attribut. –

+0

@Chris Je suis fan des balises attributaires dans une certaine mesure. Peut-être qu'un constructeur n'est appelé que pour les tests et que vous ne voulez pas que Unity l'appelle ... étiqueter le constructeur explicite et contourner Unity pendant les tests unitaires. –

+0

Je le fais via la configuration du conteneur plutôt que des attributs, idéalement. Les attributs associent le code au conteneur, et cela signifie aussi que moi, en tant qu'auteur de la classe, je fais une supposition pour chaque utilisateur de ma classe qui n'est pas vraiment à moi. –