SRP is one of the easiest principles to learn, but one of the hardest to master. The reason to this is that it can be quite hard to see if a method or class breaks SRP or not. I got a few simple rules that will help you check if you are breaking the principle.

First of all, lets check the definition of SRP:

every object should have a single responsibility, and that responsibility should be entirely encapsulated by the class

Hence my interpretation varies a bit from the original statement, as I like to apply it to classes, methods and interfaces. If you do not agree: Go buy an ice-cream, eat it, put a smile on your face and continue reading.

XmlDoc is an excellent tool if you use it correctly. So many users abuse it and screams out to the world their product/library/etc has DOCUMENTATION! The DoXZ! yay! What they fail to mention is that the documentation is simply a reflection of the methods and classes. Read my other blog posts to get a few tips on how to write good documentation. Back to SRP. Documentation can be a tool for SRP too. If you find yourself using AND’s when describing a method, class or an method argument you have most likely broken SRP. Refactor.

When talking about SRP it’s important to know what is meant with single responsibility. When it comes to methods, they should only contain logic for one type of responsibility. Here is a small example:

One might wonder why that line of code should be moved. It’s so small. In reality email validation might be larger, but that’s not really important. Following SRP usually makes it easier to follow DRY (Don’t repeat yourself) too, since you make methods smaller and let them solve a specific problem. Hence it’s a lot easier to reuse code.

If we continue to look at the method we’ll see that it also sends an email and is therefore also responsible of delivering the email. Lets move that to a new method too.

omg! We did it again. A single line method. Is this sh!t really necessary? Yep, it is. When the application grows you’ll see that you might want some templating. By using a separate method you could replace commonly used macros like #SITEURL#, #PRODUCTNAME# etc in that method instead of duplicating the code in each method that wants to send an email.

Now it’s time to move on and look at the class. Do it follow the SRP? Do it? Nooo, don’t try to fool me. I got some NINJA zkillz. promise! SendEmail and ValidateEmail has nothing to do with a class named UserService. Let’s refactor.

I’ve been working a bit more with my Griffin Framework and I’m almost ready to release the Specification library in it. The specification library is an abstraction layer similar to CommonLog and CommonServiceLocator although it contains alternatives to both of them and a bit more.

When I designed the logging interfaces I did decide to use sort of an singleton (LogManager) to be able to get a logger in each class that needs one. Since logging is such a core functionality and also well defined I didn’t see a reason to use a regular service interface which could be used in the constructor (inversion of control). imho it would only clutter all constructors since most classes will be using a logger.

The singleton facade works best for small classes that most likely will not be changed. My LogManager looks like this (comments and code contracts have been removed):

By using this approach all users can easily get a logger while the implementors have a lot of flexibility to generate the ILogManager which is used by the facade. The logging abstraction layer do actually not care about how the ILogManager is created or configured. It’s an implementation detail only know by the user of the actual logging framework.

I do not recommend anyone to use a singleton facade unless it’s absolutely required. Usually it should only be used in frameworks, your own internal one or one like this.

Compiler compiler = new Compiler();
//repeat for all types (to automatically add namespaces and assemblies to the CodeDom compiler)
compiler.AddType(typeof(string));
// compile the code. Will throw an exception if it do not work.
compiler.Compile(code);
// create an instance
var obj = compiler.CreateInstance<IWorld>();
// and invoke it
string result = obj.Hello("World!");

Note that it was a long time ago that I wrote it. The example might not work 100%. (The Compiler class do work, the example might use it incorrectly).

I’m answered a couple of questions at stackoverflow regarding the benefit of view models. Here is a summary of all my answers focusing on view models in ASP.NET MVC.

Reason 1: Remove logic from your views.

When you start working with ASP.NET MVC you’ll most likely ask yourself why you should use a view model. Using your domain model or entity model works perfectly fine. And it does. For a while. But as you continue to use your models you’ll discover that you have to add some adaptations in your views. Here is a typical usage adaptation (using razor view engine):

Not so bad, is it? The problem is that you have introduced logic into your view, which is bad for two reasons:

A) You can not unit test that code, and the only way to make sure that it works is user testing.
B) You need to repeat that code for every view that intends to use your model (code duplication = code smell)

All those small adaptations will lead to a big mess eventually.

Reason two: Security

One of the biggest advantages with view models are to remove security risks. Your database objects or domain objects will most likely contain properties that the user should not be able to change. It can be a property called IsAdmin or Reputation.

All those properties will automatically be changed by the model binder if they exist in the model (and are posted in the FORM which is quite easy to do if you know HTML). Simply remove them from the view model and they’ll never be changed.

Reason three: Loose coupling

By using domain models or entity models you are adding coupling between your lower layers and the presentation layer and that is seldom good. Google “loose coupling” to find out more.

Basically it means that if you change your domain/entity model you have to change all your views that use that model. If you use a ViewModel you only have to change the code that maps between an entity/domain model and the view model.

How to make the model mapping easier

I usually use a framework called AutoMapper to manage the mappings between viewmodels and other models. AutoMapper and it’s alternatives usually let yuo use a single line of code to do the mapping.

I was looking for a way to restrict a generic type identifier to only allow enums. Since you are not allowed to use where T : Enum I checked the metadata for Enum and found that it implements ValueType, IComparable, IFormattable, IConvertible. You cant use ValueType as restriction, but struct works fine.

In other words, use “where T : struct, IComparable, IFormattable, IConvertible” to make a type restriction which should work well as an enum restriction.

The reason to why I needed the specification is that I want to be able to fetch the DescriptionAttribute from enums. I use it to be able to add friendly names to enum values.

Use the regular XmlDoc tags to document your code, it’s usually enough to type /// in Visual studio to get the default tags.

Then use SandCastle to generate documentation. It can create regular help files, but also web based help. Remember that you have to check the “XML Documentation file” option in Visual Studio -> Project Settings -> Build -> Output.

SandCastle is not the easiest tool to work with. I usually use Sandcastle helpfile builder which is a user friendly GUI for sandcastle.

I got that exception when I loaded some options through JSON (with ASP.NET MVC). It took a lot of digging before I finally found what the cause was. And it’s not what I expected:

I’ve made a custom menu plugin in the jQuery namespace. And it seems like autocomplete tries to use ‘menu’ function ($jQuery.menu) too, which failed utterly. I removed my plugin and everything worked smoothly.

Here’s how you can use the autocomplete plugin yourself with ajax (I preload all available options):