Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dependency Injection - new instance required in several of a classes methods

I have some code that looks something like this:

public MyService(IDependency dependency) {     _dependency = dependency; }  public Message Method1() {     _dependency.DoSomething();  }  public Message Method2() {     _dependency.DoSomething();   }  public Message Method2() {     _dependency.DoSomething();   } 

Now I have just realised that because the dependency object contains internal state information. I need to new up a new instance of it in each method call

So what is the best way to do this and still not have a concrete instance newed up ?

Would you use an IoC container and make a call to to the container in each and every one of the methods? Or is there a slicker way where you can only make one call to the container?

What if I wasn't using an IoC container - would there be a way to not new up a concrete instance in each method?

like image 586
ChrisCa Avatar asked Jan 10 '11 15:01

ChrisCa


People also ask

Does dependency injection create a new instance?

If you inject a dependency into your class the container provides you a new instance for this specific dependency.

How many ways can dependency injection be done?

There are three types of dependency injection — constructor injection, method injection, and property injection.


2 Answers

Most of the answers here so far suggest that you change the injected dependency type to some sort of Abstract Factory (a Func<T> is also an Abstract Factory) to address the issue. However, if you do that it would be a leaky abstraction because you would let the knowledge of a particular implementation determine the design of the consumer. This violates the Liskov Substitution Principle.

A better option is to keep MyService as it is, and then create a wrapper for IDependency that addresses the particular lifetime issue:

public class TransientDependencyWrapper : IDependency {     public void DoSomething()     {         new MyStatefulDependency().DoSomething();     } } 

Inject that into MyService instead of directly injecting the original implementation (MyStatefulDependency).

If you want to abstract away the creation of the dependency, you can always inject an Abstract Factory at this level.

like image 90
Mark Seemann Avatar answered Sep 22 '22 21:09

Mark Seemann


It sounds like you ought to inject a provider/factory. How you represent that is up to you (and what your IoC supports) - it could be as simple as:

public MyService(Func<IDependency> dependencyProvider) {     this.dependencyProvider = dependencyProvider; }  public Message Method1() {     IDependency dependency = dependencyProvider();     dependency.DoSomething();     } 

... or you could have an interface for this specific factory type, or a generic IFactory<T> etc. There are all kinds of possibilities - but the core bit is that you inject what you need, which in this case is "a way of creating a new implementation of IDependency on each call".

like image 27
Jon Skeet Avatar answered Sep 23 '22 21:09

Jon Skeet