Performing transformations of one object type to another type is a very common task in programming. It might be publishing an event based on a command, or an externally known DTO from an internal DTO. It's pretty common to see some use of the if or switch keywords to determine the code flow. I thought I'd take a minute to show how we can go from a typical implementation using if statements to one which uses Linq and AutoMapper to reduce the coupling in the implementation.
The example code uses the following tools:
For this example, we'll have three different publishers. Each will implement a common interface: IPublisher. The implementations will be responsible for accepting a Command object and publishing the associated Event object. We'll be using two commands and events: Start -> Started, Stop -> Stopped.
The Publish method on the IPublisher interface is intentionally not using a generic declaration.
The first Publisher accepts a command. It checks the type of the command received, and calls the appropriate overload. Each overloaded method creates the appropriate event, and publishes it.
This works, but it has a few problems. It both uses an if to determine which type to publish, and manually maps the inbound command to the outbound event. That means this class is responsible for both determining what kind of event to publish and creating that event.
AutoMapper removes the responsibility of creating the event from the publisher class. AutoMapper Profiles could be used to map more complex associations, but the DynamicMap method works just fine here. Our publisher class is relieved of this responsibility, limiting it to just sorting out the type of event to be published.
It still has the problem of using the if statement to determine the type of command received (and event to be be published).
Removing the 'if'
Introducing a map from the commands and a Linq query allows us to remove the if statements. The class is still responsible for selecting the appropriate action. The concept of associating commands to events is distilled into the dictionary. This leaves the class' methods to simply select the appropriate action and execute it.
The Dictionary was left inside the publisher class to keep everything in once class. It wouldn't take much to move the mappings out of the class. This would further reduce the coupling on the Publisher. More complex mappings could be introduced by changing the Dictionary out for a custom type.
Wrapping It Up
This was a quick demonstration of removing two concerns from a class. The manual mapping of one class to another by introducing AutoMapper. The if statement was removed by introducing a map between the two types. I hope this helped describe a different was of building classes with reduced responsibilities.