Dependency Injection – Quand utiliser l’injection de propriété

J’ai une classe qui a un constructeur comme celui-ci:

private ssortingng _someSsortingng; private ObjectA _objectA; private ObjectB _objectB; private Dictionary _dictionaryA; private Dictionary<Tuple, long?> _dictionaryB; public SomeDiClass(ssortingng someSsortingng) { _someSsortingng = someSsortingng; _objectA = new ObjectA(); _objectB = new ObjectB(); _dictionaryA = new Dictionary(); _dictionaryB = new Dictionary<Tuple, long?>(); } 

Je veux obtenir la création de dépendance à partir de ce constructeur. Dans une première étape, je déplacerais les dépendances ObjectA et B vers les parameters du constructeur pour les injecter via l’injection du constructeur. Je voudrais utiliser un conteneur IoC à cette fin, c’est là que je suis bloqué pour le moment. La question est de savoir quoi faire avec someSsortingng et les dictionnaires. Je dois les injecter dans la classe, car le contenu des dictionnaires constituera une partie importante des tests unitaires. Serait-ce une bonne idée d’injecter la chaîne et les dictionnaires par injection de propriété (je n’en ai pas besoin dans les autres classes), pour que je me retrouve avec quelque chose comme ceci ?:

  private ObjectA _objectA; private ObjectB _objectB; public ssortingng SomeSsortingng { get; set; } public Dictionary DictionaryA { get; set; } public Dictionary<Tuple, long?> DictionaryB { get; set; } public SomeDiClass(ObjectA objectA, ObjectB objectB) { _objectA = objectA; _objectB = objectB; } 

Existe-t-il une meilleure pratique pour résoudre ce problème?

L’dependency injection n’est pas un objective, mais une solution à un ensemble de problèmes particulier. Par exemple, Dependency Injection facilite le remplacement des abstractions pour les tests unitaires et rend votre application plus flexible, car vous pouvez échanger, décorer et intercepter des dépendances sans que la classe consommasortingce en soit informée.

Cela ne signifie pas que vous devriez injecter toutes les dépendances d’une classe, car cela doit vous aider à rendre la classe plus testable et le système plus maintenable. Vous devez donc vous demander si, du sharepoint vue des tests, il est utile d’injecter ces dictionnaires de l’extérieur ou de rendre votre application plus flexible.

Il est difficile de répondre à cette dernière question pour moi, car votre question n’est pas suffisamment détaillée. Mais voici quelques indications:

Les seules choses que vous souhaitez généralement insérer dans une classe sont les services et les valeurs de configuration.

Un service est un contrat / abstraction / interface qui fournit «un service». Cela signifie généralement que le service fera quelque chose en votre nom, tel que calculer les prix, communiquer avec la firebase database, mettre en cache les valeurs, renvoyer l’heure du système, formater votre disque dur 🙂

Une valeur de configuration est ce qu’elle est; juste une valeur. Mais vous devez l’injecter, car il ne peut pas être codé en dur dans la classe, et vous ne voulez pas que la classe récupère la valeur elle-même depuis le ConfigurationManager , car cela créerait une dépendance cachée (sur le Configurationmanager ) et cela rendrait la classe plus difficile à tester.

D’autres éléments, tels que les primitives, les messages, les DTO, les types de collection et les entités, ainsi que tout ce qui ne fournit aucun service (logique métier) et ne constitue pas un test unitaire, ne doivent pas être abstraits et, par conséquent, ne doit pas être injecté. Dans votre cas, les dictionnaires représentent une partie de l’état interne de la classe SomeDiClass , pas un service dont dépend votre classe.

Par contre, si ces dictionnaires sont réutilisés par d’autres services, ils devront être injectés. Mais vous ne voulez jamais injecter ce dictionnaire directement, car le dictionnaire lui-même n’est pas un service. Au lieu de cela, vous devez créer une abstraction autour d’eux; quelque chose qui cache les détails de ce dictionnaire et fournit à l’application un service autour de lui.

Vous devez utiliser l’injection de propriété (ou l’injection de setter) lorsque la création d’object de votre type est hors de votre contrôle. Comme aspx Page, HttpHandler, ApiController, etc. Pour toutes les autres situations, il est recommandé d’utiliser l’injection de constructeur.

Pour résoudre les dépendances de la page aspx à l’aide de StructureMap, j’utilise l’approche suivante.

Tout d’abord, je crée une classe BasePage et utilise la méthode BuildUp () de StructureMap dans le constructeur pour résoudre les dépendances des pages dérivées. Le code est donné ci-dessous:

 public class BasePage : Page { public BasePage() { // instruct StructureMap to resolve dependencies ObjectFactory.BuildUp(this); } } public class Default : BasePage { public ICustomerService customerService { get; set; } protected void Page_Load(object sender, EventArgs e) { // can start using customerService } } public class Login : BasePage { public IAuthenticationService authenticationService { get; set; } protected void Page_Load(object sender, EventArgs e) { // can start using authenticationService } }