J'ai une interface appelée IContext
. Aux fins de cela, peu importe ce qu'il fait, sauf ce qui suit:
T GetService<T>();
Cette méthode consiste à examiner le conteneur DI actuel de l'application et tente de résoudre la dépendance. Assez standard je pense.
Dans mon application ASP.NET MVC, mon constructeur ressemble à ceci.
protected MyControllerBase(IContext ctx)
{
TheContext = ctx;
SomeService = ctx.GetService<ISomeService>();
AnotherService = ctx.GetService<IAnotherService>();
}
Donc, plutôt que d'ajouter plusieurs paramètres dans le constructeur pour chaque service (car cela deviendra vraiment ennuyeux et long pour les développeurs qui étendent l'application), j'utilise cette méthode pour obtenir des services.
Maintenant, ça ne va pas . Cependant, la façon dont je le justifie actuellement dans ma tête est la suivante - je peux me moquer .
Je peux. Il ne serait pas difficile de se moquer IContext
pour tester le contrôleur. Je devrais quand même:
public class MyMockContext : IContext
{
public T GetService<T>()
{
if (typeof(T) == typeof(ISomeService))
{
// return another mock, or concrete etc etc
}
// etc etc
}
}
Mais comme je l'ai dit, ça ne va pas. Toutes pensées / abus bienvenus.
public SomeClass(Context c)
. Ce code est assez clair, n'est-ce pas? Il déclare, that SomeClass
dépend d'un Context
. Euh, mais attendez, ce n'est pas le cas! Il ne dépend que de la dépendance X
qu'il obtient du contexte. Cela signifie que chaque fois que vous y apportez une modification, Context
celle - ci peut casser SomeObject
, même si vous ne modifiez que l' Context
art Y
. Mais oui, tu sais que tu n'as changé que Y
non X
, donc ça SomeClass
va. Mais écrire un bon code ne concerne pas ce que vous savez, mais ce que le nouvel employé sait quand il regarde votre code la première fois.