I have an interface called IContext. For the purposes of this it doesn't really matter what's it does except the following:
T GetService<T>();
What this method does is look at the current DI container of the application and attempts to resolve the dependency. Fairly standard I think.
In my ASP.NET MVC application, my constructor looks like this.
protected MyControllerBase(IContext ctx)
{
TheContext = ctx;
SomeService = ctx.GetService<ISomeService>();
AnotherService = ctx.GetService<IAnotherService>();
}
So rather than adding multiple parameters in the constructor for each service (because this will get really annoying and time-consuming for the developers extending the application) I am using this method to get services.
Now, it feels wrong. However, the way I'm currently justifying it in my head is this - I can mock it.
I can. It wouldn't be difficult to mock up IContext to test the Controller. I'd have to anyway:
public class MyMockContext : IContext
{
public T GetService<T>()
{
if (typeof(T) == typeof(ISomeService))
{
// return another mock, or concrete etc etc
}
// etc etc
}
}
But as I said, it feels wrong. Any thoughts / abuse welcome.
Could you explain why you don't like it? Maybe in an answer?
– LiverpoolsNumber9 Jan 11 '15 at 12:00public SomeClass(Context c). This code is quite clear, isn't it? It states,that SomeClassdepends on aContext. Err, but wait, it does not! It only relies on dependencyXit gets from Context. That means, every time you make a change toContextit could breakSomeObject, even though you only changedContextsY. But yeah, you know that you only changedYnotX, soSomeClassis fine. But writing good code is not about what you knows but what the new employee knows when he looks at your code the first time. – valenterry Jan 11 '15 at 14:00YinIContextwhereMyControllerBasedoes not depend on.MyControllerBaseseems to depend on every method ofIContext. This keeps true also after applying the design change I suggested in my answer. – Doc Brown Jan 11 '15 at 14:41