Thoughts on DDD and IoC

I have found that, if you drive out the dependencies of an object and express those dependencies in terms of interfaces, your domain tends to be a lot more clearly defined but that you need to rely far more heavily on your IoC container to address these dependencies. Fortunately, it also allows you to find dependency patterns far more easily and consolidate those dependencies into concrete implementations that have a focus in purpose (a.k.a. the single responsibility principle). Driving out these dependencies from the requirements of the class through interfaces leads to many small, client-specific, interfaces so that anyone that comes across the class later on and wants to try and figure out what the intent is of the code is not going to be distracted by a dependency that has been passed in that has many more methods on it than is needed by the client class itself (a.k.a. the interface segregation principle). Making these dependencies required through either constructor dependency (my personal choix de vie) or property dependency injection (not my favourite because it is more open to runtime errors) is called an inversion of control (a.k.a. the dependency inversion principle)  leads to strong reliance on an Inversion of Control container.  This method of designing classes and driving out features are two of the three principles of SOLID design.

SOLID is not new (thank you Uncle Bob!) and I think that many of the concepts are generally agreed upon by most developers concerned with good design. What I want to do in this article is try and illustrate how this changes the way you develop your code.

In the first scenario, I am responsible for building a class that shows the name of the application in the title bar of the application window. We’re trying to develop a really strong architecture with as few points of failure as possible so that we can make a change in one spot and it corrects the bug in other spots as well.

  • Whether I am using MVP, MVC, MVVM, or straight code-behind classes I’ll have a class that is connected to the User Interface screen (webpage, windows form, mobile device screen, whatever).

class MainPageBackingClass {
        // Public property the UI uses to provide the Application Name in the title bar
        public string TItleBarText { get { } }
}

  • There’s a desire to provide localization for our application and that’s going to be provided somewhere else in our application. My class needs to get the string that puts the application name up on the screen.

class MainPageBackingClass {
        public MainPageBackingClass(IMainPageBackingClassStringsProvider stringsProvider) { .. }
        // Public property the UI uses to provide the Application Name in the title bar
        public string TItleBarText { get { return  stringsProvider.ApplicationName; } }
}

interface IMainPageBackingClassStringsProvider { string ApplicationName { get; } }

At this point I don’t care, from the design of my class’ perspective, what is implementing IMainPageBackingClassStringsProvider, I just care that I need something to provide that string for me. The subtle point to notice here is that the class is defining what it needs and driving out it’s dependencies. There is an interface (IMainPageBackingClassStringsProvider) that is providing only the single string. That’s okay.

Okay, I’m done and I feel good about myself. My next assignment is to create a class that assembles an email message. It puts the user’s name in the formatted message.

  • I need a class that takes a format-able string and puts the user’s name in it.
class MessageBuilder { }

  • It’s going to need something to provide the formatted message to it.
class MessageBuilder {
        MessageBuilder(IFormattedMessageProvider messageProvider) { … }
}

interface IFormattedMessageProvider { string FormattedMessage { get; } }

  • And now a method that takes in something that provides the user’s name
class MessageBuilder {
        public string Format(IUserNameProvider userNameProvider) {
               return string.Format(messageProvider.FormattedMessage, userNameProvider.UserName);
        }
}

interface IUserNameProvider { string UserName { get; } }

In my application I now have three dependencies (IMainPageBackingClassStringsProvider, IFormattedMessageProvider, and IUserNameProvider). There’s an emerging pattern here that there are at least two dependencies requiring strings. Since a class can implement multiple interfaces without any problem, I am going to build a class that has a singular purpose (to provide localized strings) and implement both interfaces.

class StringsProvider : IMainPageBackingClassStringsProvider, IFormattedMessageProvider {
         public string ApplicationName { get { return “Hello World”; } }
         public string FormattedMessage { get { return “Welcome {0}!”; } }
}

Now, here’s the kicker of this entire scenario. There’s a temptation for us to consolidate all of those strings that are being provided by the StringsProvider class into a single interface (maybe call it IStringsProvider) and have both the MessageBuilder class and MainPageBackingClass have a dependency on a single interface. On first inspection, that would appear to a good idea. The issue comes that a later developer might get confused as to the intent of the code in one of the classes if there are more methods/properties available to them than is needed by the class. If, for example, it ended up that you had two interfaces, one provided ApplicationName as a string and another providing ApplicationTitle as a string.

From within the context of separate interfaces, each class relying on an interface providing only the single string, it would be easy for the developer to know which string they were to be using within the class. It wouldn’t be confusing because there’s only one property to choose from. If, though, we had consolidated those string providing dependencies into a single interface, we now have two properties (ApplicationName and ApplicationTitle) being provided by this interface. Which one should I, as a developer of MainPageBackingClass choose? What if there are hundreds of other properties to choose from in my consolidated interface that I now have to scan through and guess which one I really need to use? It’s much easier to express the intent of the code through individualized interfaces.

Interfaces are the cheapest thing to produce in code.

Luckily classes can implement multiple interfaces (even hundreds if need be) and there’s always your IoC container that can produce all the magic to get your class the one it needs at run-time.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s