3

I've been using a lot dependency injection, test-driven development, and unit-testing lately and am starting to love it.

I am using constructor dependency in classes, so that I can then inject mock dependencies for unit-testing.

However, what are the best way to deal with it, when you actually want the objects in the production environment?

Do you use DependencyInjectionContainer.Get<MyClass>() everywhere you want to create the class? Or does it make more sense to create a blank constructor for the class, which resolves all the dependencies via the DI container?

Karl Cassar
  • 6,043
  • 10
  • 47
  • 84
  • Related: http://stackoverflow.com/questions/4835046/why-not-use-an-ioc-container-to-resolve-dependencies-for-entities-business-objec – Steven Feb 15 '13 at 16:21

1 Answers1

2

There's no need to have a default constructor.

In your production code you would typically have just a single call to DependencyInjectionContainer.Get(someRootType) in your application to get a root type (for instance a HomeController class in MVC). Since all types are created using constructor injection, the container will be able to create the whole graph of related objects for you. So from a production perspective there is no need to have more than one constructor.

Since in your unit tests you would typically want to inject all the mock objects, your tests won't use the default constructor either. On the other hand, letting each test call the constructor of the class under test directly would soon result in code that gets hard to maintain, since you will have to change all tests when the constructor changes. Instead, centralize that logic to a factory method within the test class. This factory method can have multiple overloads to make it easy for the tests to create the class under test.

Steven
  • 166,672
  • 24
  • 332
  • 435
  • thanks, the explanation I was hoping for :) However, what would you do when you want to 'new()' the item, e.g `var product = new Product();`. Would you do something like `var product = DI.Get();`? – Karl Cassar Feb 14 '13 at 18:20
  • 1
    Entities are short lived and are typically not created by the container. They would normally be created by an `IUnitOfWork` or `IRepository`. – Steven Feb 14 '13 at 18:37
  • 1
    @KarlCassar: To add to what Steve said: "Serivce" type objects are constructed and wired together by the DI container. The service objects can create "entity" objects. The DI definition defines which service talks to which service, the services themselves talk to each other by passing entities. – WW. Feb 15 '13 at 02:18
  • So if I have an entity like `Product`, and it has a method which requires the use of a service, it makes sense to inline it as say `DI.Get.GetRelatedProducts(this)`. Note this is just an example, not actual code. – Karl Cassar Feb 15 '13 at 14:19
  • The code that calls the entities method (I assume you apply DDD) is a service and will have its dependencies injected into its constructor. You can pass those dependencies to the entity using method injection. I'd assume something like this: `void Handle(ProcessProductCommand command) { var product = this.repository.Get(command.ProductId); product.AssignValue(this.eventProcessor); }`. – Steven Feb 15 '13 at 16:24