LP on .NET

June 3, 2012

Writing Explicit Code with Dependency Injection

Filed under: .NET,C#,Software Development — Larry Parker @ 5:30 pm

It seems that I can’t say enough about dependency injection these days.  It gives me an incredible amount of control over my code in the form of testability and modularity.

One of the additional benefits I have gained by following this pattern is that my code has become more explicit.  What do I mean by that?

Consider the following example of “classic” programming:

CustomerDataManager customerDataManager = new CustomerDataManager();

Customer customer = customerDataManager.GetCustomerById(1001);

This code is simple enough.  We just create an instance of our customer data manager, call the GetCustomerById method, and get our customer back.  The GetCustomerById method hits the database with the appropriate SQL statement (or using some other data access technology) and we’re done.  The code looks like this:

public class CustomerDataManager
{
    public CustomerDataManager()
    {
        _connString = ConfigurationManager.ConnectionStrings["MainDbConnectionString"].ConnectionString;
    }

    private String _connString;

    public Customer GetCustomerById(Int32 customerId)
    {
        Customer customer = ... // hit db using above connection string

        return customer;
    }
}

Note the connection string obtained in the constructor using the .NET ConfigurationManager class.  This requires your app to have the following in its app.config file:

<configuration>
  <connectionStrings>
    <add name="MainDbConnectionString" connectionString="Data Source=.; Initial Catalog=TheDb; etc...;"/>
  </connectionStrings>

And we’re done.  The customer data manager can now be used by anyone on your team.  All that they need to know is that their executable’s app.config file needs a connection string called MainDbConnectionString.  But you’ve documented that (right? Smile), so that won’t be a problem for anyone.

Well, it turns out that the developers on your team using your CustomerDataManager class already have their own connection string defined in their executable’s app.config and it’s not called MainDbConnectionString.  You ask them why it’s not called MainDbConnectionString.  They ask you why you’re not calling it ApplicationDbConnectionString.  And like the north and south going Zax, you just stare each other down with your arms folded.

OK, hopefully it’s not that bad.  But why even go there?  Why have your data manager define an external dependency like an app.config setting in the first place?

The way around this whole thing is to just inject the connection string into the constructor and remove the dependency.

Let’s rewrite our customer data manager’s constructor to handle this:

public CustomerDataManager(String connString)
{
    _connString = connString;
}

Now your CustomerDataManager class is out of the business of app.config settings.  It doesn’t know or care anything about configuration and doesn’t need to access the dubious ConfigurationManager class (dubious because it makes it so easy to create dependencies like this).

And now your CustomerDataManager class can be used by the developer who gets all of his connection strings from an encrypted XML file, and can also be used by the other guy who gets them from the registry (using his own encryption algorithm, of course).  They don’t mind passing the connection string into your data manager and can’t stop talking about how easy your classes are to work with.

You’re a hero.

All because your code was explicit and didn’t make any assumptions about its runtime environment.

Advertisements

Create a free website or blog at WordPress.com.