0

I'm (somewhat) new to DI and am trying to understand how/why it's used in the codebase I am maintaining. I have found a series of classes that map data from stored procedure calls to domain objects. For example:

Public Sub New(domainFactory As IDomainFactory)
  _domainFactory = domainFactory
End Sub

Protected Overrides Function MapFromRow(row As DataRow) As ISomeDomainObject
  Dim domainObject = _domainFactory.CreateSomeDomainObject()
  ' Populate the object
  domainObject.ID = CType(row("id"), Integer)
  domainObject.StartDate = CType(row("date"), Date)
  domainObject.Active = CType(row("enabled"), Boolean)

  Return domainObject
End Function

The IDomainFactory is injected with Spring.Net. It's implementation simply has a series of methods that return new instances of the various domain objects. eg:

Public Function CreateSomeDomainObject() As ISomeDomainObject 
  Return New SomeDomainObject()
End Function

All of the above code strikes me as worse than useless. It's hard to follow and does nothing of value. Additionally, as far as I can tell it's a misuse of DI as it's not really intended for local variables. Furthermore, we don't need more than one implementation of the domain objects, we don't do any unit testing and if we did we still wouldn't mock the domain objects. As you can see from the above code, any changes to the domain object would be the result of changes to the SP, which would mean the MapFromRow method would have to be edited anyway.

That said, should I rip this nonsense out or is it doing something amazingly awesome and I'm missing it?

Swoogan
  • 5,298
  • 5
  • 35
  • 47

1 Answers1

0

The idea behind dependency injection is to make a class (or another piece of code) independent on a specific implementation of an interface. The class outlined above does not know which class implements IDomainFactory. A concrete implementation is injected through its constructor and later used by the method MapFromRow. The domain factory returns an implementation of ISomeDomainObject which is also unknown.

This allows you supplement another implementation of these interfaces without having to change the class shown above. This is very practical for unit tests. Let's assume that you have an interface IDatabase that defines a method GetCustomerByID. It is difficult to test code that uses this method, since it depends on specific customer records in the database. Now you can inject a dummy database class that returns customers generated by code that does not access a physical database. Such a dummy class is often called a mock object.

See Dependency injection on Wikipedia.

Olivier Jacot-Descombes
  • 104,806
  • 13
  • 138
  • 188
  • So you're saying I should just ripe it out then? Since there will only ever be one implementation of IDomainFactory that returns the only implementation there will ever be of ISomeDomainObject? – Swoogan Nov 15 '12 at 19:56
  • Yes you can, if don't want to benefit from the advantages of DI. Note: You can also use DI without a DI Framework like Spring.NET. Just work with interfaces and create and inject your objects "manually". – Olivier Jacot-Descombes Nov 15 '12 at 20:02
  • I'm confused. What benefits am I currently experiencing that I would lose? How is this code not testable wo/ DI? Under what concrete scenario would I change the implementation of ISomeDomainObject at runtime? Why would I complicate my code for a potential future scenario that may never exist? I understand the general case for DI. What I don't get is how it's a good idea in this specific case. – Swoogan Nov 15 '12 at 21:41
  • I can only speak in general terms. You must decide for your specific case. If your domain objects are simple data objects with no logic in them, there is not much to be tested. But things could be different for your database access component (the code above). If you decide to access a different database one day, it will be a great advantage being able to just inject a different database access component. All you will have to do is to write a new db access component, the rest of the application remains unchanged. Once you get used to this way of programming you will not want to go back. – Olivier Jacot-Descombes Nov 16 '12 at 14:27
  • The system is using DI for the database access, so I'll keep that. Curiously, it's not using it for web service calls. I think I will remove it from the domain objects and add it to the WS calls. Thank you for your advice. – Swoogan Nov 20 '12 at 16:26