This question already has an answer here:
Sorry about the ambiguous title, but I wasn't sure how to phrase it.
I am looking for any thoughts on whether the following would be a poor usage of an injected object. I have an IOC container set up in my application (I am using Unity, but I don't think that really matters for this). I was wondering if it is bad practice or if there is any catch to setting a variable in the constructor from the injected interface implementation without ever setting the injected implementation to a private variable.
In the example below, injectedClass
is injected into the constructor by my IOC container. Typically, I would set injectedClass
equal to a private instance of IInjectedClass
, but since I am only going to use it to set that single variable, I am just setting the variable it in the constructor and then forgetting about the injected item.
public class SomeClass
{
private string _someVariable;
public SomeClass(IInjectedClass injectedClass)
{
_someVariable = injectedClass.GetSomeString();
}
public void SomeMethod()
{
Console.WriteLine(_someVariable);
}
}
Is there any reason that the above code would be a bad practice? Or is the only argument against it that if I wanted to use the injectedClass again, it would not be available?
Thanks for any thoughts
I don't see a problem with that. However, you could also inject the string immediately. You could explicitly tell your container that a parameter with name
x
should be filled with a certain string.If you do it that way, you're not creating a dependency on
IInjectedClass
.There are several problems with doing this. One is that it violates Nikola Malovic's 4th law of IoC.
In another answer here on Stack Overflow, I've outlined the various motivations for this rule.
In this particular case, there's the additional problem that it makes your class harder to reason about. When you look at the class as a black box (which is what all encapsulation is about), this is what you see:
It looks as though
SomeClass
requiresIInjectedClass
, but it turns out that it really only needs a string. This makes it more difficult to use, because you have to supply a completeIInjectedClass
instance, when all you could have gotten away with was a string. You could say that this violates Postel's Law.A better alternative is to be honest about the dependencies and request the string as a Primitive Dependency: