Friday, August 8, 2014

Dependency Injection and Single Responsibility Principle

I referenced the Single Responsibility Principle(SRP) in my previous blog posts and now it's time to see it in action. Lets start with the basics

 Wikipedia defines the SRP like this: “[T]he single responsibility principle states that every object should have a single responsibility, and that responsibility should be entirely encapsulated by the class. All its services should be narrowly aligned with that responsibility.”

So what does this mean to you and how you code? Well lets look at some code that doesn't and then does follow the SRP.

So now our Services only handle one type of object. From here anything that would send back a User would go through the UserService and Groups through the GroupService. The hidden refactor here is in the Repository layer. They too have been refactored to specific types. This is a simple example and doesn't look like it has very much use right? Wrong. Lets delve into this a little more.


The presentation layer could be a Web Page or a Winform or even a command line app. In the grand scheme of things it doesn't matter and in fact they could be interchangeable. Same with the Data Tier layer. Lets say you choose to use Fluent Nhibernate for the data layer as a wrapper for your database. If your data layer only holds the mappings and the data objects then at any point in your application you could swap to Entity Framework and keep on rolling with very little (if any code change). The key to allowing this to happen is the Logic Layer or Core as I will be referring to it from here on.

4 layer architecture (I suck at graphics sorry)


The Core layer should hold all your business logic. The repository layer will talk to the Data Layer as a proxy for Core. Core will hold ALL of the contracts (interfaces / abstract classes) that will be injected. That means Core does not have a reference to anyone but everyone has a reference to core.

So why do I have a repository layer you ask? I prefer to use the Repository Pattern in conjunction with my ORM. This allows for testing and if I swap out my ORM I just need to ensure that the new orm's Data Contexts, Inherit from the Interface I wrapped around the previous type.

If all of the business logic is in Core how is it possible not to reference any other project? Two words: Dependency Injection(DI)!! I will cover a brief description of using DI but it has far more features then I will cover here. (note: the Core will reference the Data Layer you will see why below)

I will be using Ninject for all of my examples. There are A LOT of DI frameworks out there. Pick the one that works best for you.

So remember up above when I told you that Interface that was being passed as a parameter to the constructor on the service was dependency injection? Well that is half of the battle. The other half is the Inversion Of Control(IoC) Container. Some of this IoC is specific to MVC but it can be adjusted to use in WinForms applications.


The magic happens on line 12. This Binds a concrete type to the Interface that we passed in. Now any constructor that requires a parameter of type IUserRepository; Ninject will pass a concrete type of UserRepository behind the scenes. BOOM!! Now everybody knows Core, but he doesn't know them.


So why on earth would you want to go through all of this? Unit testing. Doing this allows us to test each method in each class (unit) and we can Mock / Stub the things that do not directly effect this class. Also see: this.

Now one last note. If you read my last blog post; then you know about Automapper. Your presentation layer should NEVER use your data objects.

I like to create an infrastructure folder in my Core layer and Create Objects for the Presentation layer to use. I then wrap my new Presentation Layer object and the Data Layer object in the same interface (as long as the data layer objects are not named horribly) and then user Automapper to map from one to the other in the Core layer. Then I have Presentation Layer objects that live in Core (presentation layer has a reference to Core) and Data Layer Objects that live in the Data Layer (this is where Core needs the reference to Data) that get converted in the Core layer and passed along to their appropriate targets.

Now if you swap out the Presentation Layer. Your new Display objects just need to inherit from the Interface that wraps the Data Layer (or if horribly named, the Interface that you chose with better names) and off you go. If you swap out the Data Layer you can do the same thing.

In conclusion. If I was to give another developer my Core project, they could create an app with the same business rules in technologies that they are more familiar with. When the business rules change you are only editing one spot. All these things in mind no matter what type of development you do (web, console, command line) if you keep everything separate, Maintenance is far easier.

Robert T. Frey


AutoMapper

In my previous post I explained the usage and benefits of Entity Framework (EF). You will notice in the repository section I mentioned map the new object to the existing one for an update. So, on that note mapping objects from one object to another is something developers deal with on a regular basis. In general there are many ways to map one object to another.

One way to map these objects is:

What if you could map these two objects with fewer lines of code?

A couple things of note here. You can only do .ReverseMap() if both objects have the same values. If the objects do not have the same values will need to map them manually.

You will notice that the AGE value is not listed. The names match up so AutoMapper(AM) does this for us automatically. At this point your probably screaming "WAIT!!! You didn't map the lists of strings correctly!!!." Incorrect my dear friend. That is AM magic. You see behind the scenes AM is actually creating those objects and mapping the objects in the same way as I did in the second example.


Okay so a couple side notes. I am not a VB developer. I don't know how to do generics in vb so the code doesn't match. Also the converter I use to convert C# code to VB.NET wouldn't / couldn't convert my code. If it is wrong syntactically. Let me know I will fix it.

Back on point. As you can see behind the scenes AM does the same thing as above it just does it behind the scenes. As long as you write a Mapper for two objects you can map the two as Collections.

So I have mentioned before that I try very hard to follow the Single Responsibility Prinicple.(SRP) What does this have to do with Automapper you ask? Well if in your AutoMapperConfigurator.Configure() method you have several different types of object mappings, then your not following SRP. So I am gonna go over the way I handle that. I will not say this is the best way. I will just say I find it the easiest.

AM's Configure method actually exists on the Profile Object. That being said you inherit from this object and override the Configure method.


Before LinqKit released that extension method I created one for my own use and now you have it if for some reason you cannot use LinqKit's built in method. So in the code above. The Configure() method now gets all of the objects that inherit from Profile and Create an instance of them. Essentially your initializing all of your mappers just like you would if you were to put them all in the Original Configure method.

In conclusion: AM is an excellent tool especially if your mapping many objects from one type to another. With very little setup you can map any object to another. Your code will be cleaner and easier to read in some places.

Robert T. Frey

Entity Framework

If all of your databases already exist and you are acting upon existing data. Entity Framework 6(EF) allows you to to build an Entity Data Model XML(edmx) file based on an existing database. You can see an excellent tutorial here. EF is an Object to relational Mapping (ORM ). What EF gives you is actual objects or DbSet's to act upon with linq.

As you can see it built our Database structure and gave us DbSet's that match our tables, and methods to match our Stored Procedures. Now lets look at the individual table objects.

C# is cleaner because of Auto Properties. But on either account you can now access your data layer using linq and get data objects that will directly map back to the database. Now we can wrap this functionality in a repository so that our data layer can be separated from your service code.(Single Responsibility Principle)
Now we have covered all of our CRUD actions. Using EF allows you to act on the data layer without using Stored procedures for all of your CRUD actions.

Now you have seen how EF gives you access to existing objects, but what if we want to extend one of those objects or even add an Interface to one of them so that we can use Dependency Injection? Well EF uses partial classes to construct all of the entities and models. So we can extend them or wrap them in interfaces by making our own object of the same name.


In conclusion: EF is a wrapper for your Database and with the ability to create our objects from existing tables we can quickly write code to do any action needed against the database. We also get our existing stored procedures so you don't have to "reinvent the wheel".

Robert T. Frey