I found a few articles outlining the reason why the DependencyResolver in C# MVC should be avoided
But I also found a pattern of injecting a "base dependency" into a constructor, and that class essentially hold all instances the app's dependencies, but obviously not in a sigleton, each time the dependencies are instantiated anew
// example possibly to be avoided
public interface IBaseDependencies
{
IClientRepo ClientRepo { get; }
IProductRepo ProductRepo { get; }
/// more here
}
..but while I love the simplicity of passing dependencies in this way, the problem is ALL the depencies will be instantiated but they may not all be required, so to avoid that performce hit, I thought to add C#'s Lazy<> class like so...
// Is this example any better?
public interface ILazyBaseDependencies
{
#region IClientRepo
private readonly Lazy<IClientRepo> ClientRepoLazy =
new Lazy<IClientRepo>(() => DependencyResolver.Current.GetService<IClientRepo>());
public IClientRepo ClientRepo => ClientRepoLazy.Value;
#endregion
/// more here
}
So now the dependency is only instantiated when it is called directly. The larger the project, the more the "base dependencies" approach becomes useful, but will it hurt performance to do this this way?
I wouldn't call that a pattern, but rather a code smell. At the very least, it violates the Interface Segregation Principle as well as the Dependency Inversion Principle.
Will it hurt performance? Only you can answer that question.
Related
In my current project my manager is forcing some design concept for dependency injection I would like to discuss because I’m curious what a specialists of dependency injection think about this approach. The ideas behind this is use of class called catalog that is implemented per each service (service in Service Fabric) and having all dependencies inside like this:
public interface IDepA
{
}
public interface IDepB
{
}
public interface IDepC
{
}
public class StandardConstructorInjectorService
{
private readonly IDepA _depA;
private readonly IDepB _depB;
private readonly IDepC _depC;
public StandardConstructorInjectorService(IDepA depA, IDepB depB, IDepC depC)
{
_depA = depA;
_depB = depB;
_depC = depC;
}
}
public class ServiceCatalog
{
private readonly Container _container;
public ServiceCatalog(Container container)
{
_container = container;
}
public IDepA DepA => _container.GetInstance<IDepA>();
public IDepB DepB => _container.GetInstance<IDepB>();
public IDepC DepC => _container.GetInstance<IDepC>();
}
public class ServiceWithCatalog
{
private readonly ServiceCatalog _catalog;
public ServiceWithCatalog(ServiceCatalog catalog)
{
_catalog = catalog;
}
}
From my perspective we have
Pros:
Code that is using catalog is simple
Dependencies can be used in Lazy mode so when code logic is not using them they will not be created – but on other hand I know that we should design classes in such way that they will use all dependencies
It is easy bootstrap those classes because they have one predefined catalog
Cons:
Dependencies to class is not directly visible
Smell for service locator but we use resolve only in catalog definition and not in business code so I’m not sure is this acceptable or maybe dependency injection police will hunt us down :)
What do you think about this approach?
Your ServiceCatalog class depends on the Container. This effectively makes this a Service Locator, which is an anti-pattern. The fact this this class is not 'business code' is irrelevant. The only thing that matters is that it is not part of the Composition Root, which makes this an anti-pattern.
Besides using an anti-pattern, the class exposes its dependencies, rather than hiding them, which is a bad idea as well. The main idea of this class is probably to group commonly used dependencies together, lowering the number of constructor dependencies a class has. Problem with this, however, is that it doesn't lower the complexity of a consuming class, but simply obscures the fact that a class has too many dependencies. A class with too many dependencies likely violates the Single Responsibility Principle.
Instead of using this service catalog 'pattern', stick to using Constructor Injection. When a class gets too many constructor dependencies, a code-smell called Constructor Over-Injection, action should be taken. There are many solutions for this, such as Facade Services, Decorators or Domain Events. A Facade Service hides its dependencies rather than exposing them.
All this information, and much more, can be read in this book, by Mark Seemann and myself.
I am using Ninject, and using Constructor Injection:
An example of my problem is
I have two interfaces with their implementations.
1. IUsersProvider
2. ICompaniesProvider
I need to use functions from UsersProvider in CompaniesProvider
And from CompaniesProvider in UsersProvider
So I have created Constructors in both classes:
public class UsersProvider : IUsersProvider
{
private readonly ICompaniesProvider _companiesProvider;
public UsersProvider(ICompaniesProvider companiesProvider)
{
_companiesProvider = companiesProvider;
}
}
AND
public class CompaniesProvider : ICompaniesProvider
{
private readonly IUsersProvider _usersProvider;
public UsersProvider(IUsersProvider usersProvider)
{
_usersProvider = usersProvider;
}
}
Now this code compiles ok but from an architecture point of view this not correct (It looks like a circular reference). Ninject throws an exception when I run this code:
what is the best way of handling the scenario to use functions from each class in the other?
The correct way to handle this scenario would be to refactor one or both interfaces/classes so that they don't depend on each other. It's hard to advise with more detail without seeing the code of each, but typically if you find yourself in this situation, one or both of your classes are doing too much, i.e., violating Single Responsibility Principle. split up the interface so it only does one thing, and then your dependencies should clear up.
I have a C# class which instantiates on its own a NetworkCommunicator class. I'd like to mock out the NetworkCommunicator class for my unit test, and replace it with a pretty simple stub.
But the NetworkCommunicator is never passed as a parameter. It's created by the class being tested.
In Ruby, this is easy to mock out. In Java, this is why you need Dependency Injection, which is too heavy for this project. Is there a simple way to mock this out in C#, perhaps using Moq or something similar?
You mentioned that DI is too heavyweight for this project, why not try some Truck Driver's DI, thus:
public interface IDependency
{
void DoSomeStuff();
}
public class ClassUnderTest
{
private IDependency _dependency;
public ClassUnderTest(IDependency dependency)
{
_dependency = dependency;
}
public ClassUnderTest() : this(new Dependency())
{}
public void ImportantStuff()
{
_dependency.DoSomeStuff();
}
}
Using this constructor chaining technique, you can now mock the IDependency all you want, without worrying about hooking up DI or IoC.
Create a "TestClass" that inherits from your class under test.
Override that parameter with a mocked instance
Create a property on the class under test that returns the new instance
public class ClassUnderTest {
public string MethodYouAreTesting(int someInput) {
var networkCommunicator = GetNetworkCommunicator();
// Do some stuff that I might want to test
return "foo";
}
public virtual NetworkCommunicator GetNetworkCommunicator {
return new NetworkCommunicator();
}
}
[TestFixture]
public class ClassUnderTestTests {
public void GivenSomeCondition_MethodYouAreTesting_ReturnsFooString() {
var classToTest = new TestClassUnderTest();
var result = classToTest.MethodYouAreTesting(1);
Assert.That(result, Is.EqualTo("foo");
}
}
public class TestClassUnderTest : ClassUnderTest {
public override GetNetworkCommunicator {
return MockedNetworkCommunicator;
}
}
I read of this technique this in the "Art of Unit Testing" and use it frequently when refactoring to full DI doesn't make sense or when the class I'm testing isn't something I can change.
Hope this helps.
You should refactor your code and pass dependencies in. You can also use typemock as easier to use alternative to fakes in Visual Studio 2012.
There's the built-in Fakes system, pretty well described at http://msdn.microsoft.com/en-us/library/hh549175.aspx
If that is too heavy-weight for your use case you might find the PrivateObject class more useful.
I have a C# class which instantiates on its own a NetworkCommunicator class.
As you noticed, this is a show stopper in C# when you want to mock this thing out. Solution is simple, and depends on context/purpose of the instantiated class:
inject it as a dependency if it's reusable component
provide it via factory if it's something that should be created every time when demand comes in
Either way, you'll need DI (factory from the second example is naturally injected too).
In Java, this is why you need Dependency Injection, which is too heavy for this project.
Is dependency injection too heavy? DI is design pattern, it's only too heavy when used when it's not really needed. Your question clearly shows you need it. Perhaps you meant that DI container is too heavy for your project? This might be true, as depending on project's complexity, you should choose appropriate way to apply DI.
I'd like to raise one more point to be aware of when applying solution like the one proposed in Greg Smith's answer. Essentially, your API ends up with constructors:
public TestedClass() : this(new Dependency()) ...
public TestedClass(IDependency) ...
As appealing as it might be at first glance, when long-term perspective is taken into account, several issues start to emerge:
does TestedClass must have IDependency or can it do fine without it?
what default (parameterless constructor) defaults to (implementation detail-level knowledge is required to use it properly)?
it creates tightly coupled components (TestedClass assembly will possibly have to reference other assembly - Dependency's assembly, even though it might not be relevant to it anyhow)
This is an anti-pattern going under different names, e.g. Bastard Injection. Of course, some of those problems might be mitigated (like making constructor protected/internal or having default implementation in the same assembly), but the anti-pattern and its long-term consequences remain. Also note that it's by no means more simple, faster or less code than regular DI.
You'll have to ask yourself what's less heavy - applying proper DI, or going you ways around with anti-patterns and/or 3rd party frameworks (MS Fakes).
I just proposed the following pattern for someone else. I have used it a few times, when I wanted the ability to inject dependencies for test, but but still wanted this backdoor (somewhat) invisible to outsiders. Hence, the empty public ctor and internal ctor with the argument:
public class ClassThatUseInjection
{
private readonly SomeClass _injectedClass;
public ClassThatUseInjection(): this(new SomeClass()) {}
internal ClassThatUseInjection(SomeClass injectedClass)
{
_injectedClass = injectedClass;
}
}
public class SomeClass
{
public object SomeProperty { get; set; }
}
My idea was that since the empty ctor does nothing but forward with a new instance, my crime is not too bad. What do you think? Is is too smelly?
Regards,
Morten
I think it is ok. In fact, what you are doing with injecting the class is Dependency Injection and a practical use of the Open/Closed Principle.
I don't even see no harm in making that internal ctor into a public one.
My problem with this is always, that I don't want to force others to create an instance of the injected class, therefore, the default ctor. But if they want to create an instance, they can go ahead and do so.
On a related note: IMHO, you should use an interface instead of a class, otherwise, I don't see too much advantage in passing that class in the first place...
It's called "poor man's dependency injection", if you can't get a proper IOC container into your app its a reasonable alternative although you would be better off with the power a container gives you.
Jimmy Bogard has a good write up here
wanted this backdoor (somewhat) invisible to outsiders
Making it internal successfully does that, IMO.
The down-side is that it puts your tests in the same assembly.
See also Hide public method used to help test a .NET assembly about how to hide public methods if your tests are in an external assembly.
Edit: what you've done is especially appropriate, if SomeClass is logically internal ... if it's an implementation detail which shouldn't/needn't be exposed in the assembly's public interface.
Let's say we have
public interface ITimestampProvider
{
DateTime GetTimestamp();
}
and a class which consumes it
public class Timestamped
{
private ITimestampProvider _timestampProvider
public Timestamped(ITimestampProvider timestampProvider)
{
// arg null check
_timestampProvider = timestampProvider;
}
public DateTime Timestamp { get; private set; }
public void Stamp()
{
this.Timestamp = _timestampProvider.GetTimestamp();
}
}
and a default implementation of:
public sealed class SystemTimestampProvider : ITimestampProvider
{
public DateTime GetTimestamp()
{
return DateTime.Now;
}
}
Is it helpful or harfmful to introduce this constructor?
public Timestamped() : this(new SystemTimestampProvider())
{}
This is a general question, i.e. timestamping is not the interesting part.
I think it depends on the scenario, and is basically a function of who the consumer the code is (library vs. application) and whether you're using an IoC container or not.
If you're using an IoC container, and this is not part of a public API, then let the container do the heavy lifting, and just have the single constructor. Adding the no-args constructor just makes things confusing, since you'll never use it.
If this is part of a public API, then keep both. If you're using IoC, just make sure your IoC finds the "greediest" constructor (the one with the most arguments). Folks not using IoC, but using your API will appreciate not having to construct an entire dependency graph in order to use your object.
If you're not using an IoC container, but just want to to unit test with a mock, keep the no-args constructor, and make the greedy constructor internal. Add InternalsVisibleTo for your unit test assembly so that it can use the greedy constructor. If you're just unit testing, then you don't need the extra public API surface.
i wouldn't provide that constructor. Doing so makes it far too easy to call new TimeStamped and get an instance with new SystemTimestampProvider() when your IoC may be configured to use OtherTimestampProvider().
End of the day you'll end up with one hell of a time trying to debug why you're getting the wrong timestamp.
If you only provide the first constructor you can do a simple find usages of SystemTimestampProvider to find out who is (wrongly) using that provider instead of the IoC configured Provider.
In general I don't think so... It depends on what you're using Dependency Injection for. When I use DI for unit testing, I do the same thing (more or less) by instantiating the production version of the dependant object when the injected instance is null... And then I have an overload that does not take a parameter and delegates to the one that does... I use the parameterless one for production code, and inject a test version for unit test methods...
If you're talking about a IOC container application, otoh, you need to be careful about interfering in what the configuration settings are telling the container to do in a way that's not clear ...
public class EventsLogic
{
private readonly IEventDAL ievtDal;
public IEventDAL IEventDAL { get { return ievtDal; } }
public EventsLogic(): this(null) {}
public EventsLogic(IIEEWSDAL wsDal, IEventDAL evtDal)
{
ievtDal = evtDal ?? new EventDAL();
}
}
I try to avoid this - there are a few places where I've found it to be a useful design but more often than not I've found it just leads to me making mistakes that can be a little puzzling to work out.
The need for the default injected objects is greatly reduced by using a dependency injection container (I use StructureMap) to manage all this wiring - the DI container makes sure that you always get a concrete instance you can use.
The only place where I'm still tempted to use the constructor you suggest is in my unit tests but recently I've been getting far greater value out of using fake or mocked objects.
There are places where having the default dependant objects is the correct and useful design, but in general I'd say that you are just introducing tight coupling that doesn't add a lot of value.
It's neither helpful nor harmful. It poses an aesthetic problem in that you are limiting your DI to constructor injection only when your design may allow for property setter injection.
Another option would be to implement a getter that returns a default implementation:
public DateTime Timestamp
{
get { return _timestampProvider??new SystemTimestampProvider(); }
set { _timestampProvider = value; }
}
Alternately, you can implement the above using a singleton if you're worried about creating too many objects in the heap.
My team has a great deal of success using this method. I recommend one change: Make _timestampProvider readonly. This forces the provider to be deterministic at construction and will eliminate bugs.
public class Timestamped
{
private readonly ITimestampProvider _timestampProvider;
public Timestamped(ITimestampProvider timestampProvider)
{
_timestampProvider = timestampProvider;
}
public Timestamped(): this(new SystemTimestampProvider())
{ }
}
That said, we are always looking at new technologies, including DI frameworks. If we ever abandon this technique for something significantly better I'll let you know.