Recently, I’ve caught myself that I was creating decorator around interface which has quite a few methods. I was interested only in one particular method, whereas for the others I had to delegate a call to the decoratee. Thus, it was tedious. This leads me to searching a way for doing this task automatically.

Apart from that, we could argue that the interface does not follow Integrace Segregation Principle as Robert C. Martin pointed out that >Clients should not be forced to depend upon methods that they do not use.

Unfortunately, we often work with code which we can’t change and that’s the case here.

Know your tools

I use ReSharper, so at the beginning I started to look if it can help with that. I started with the following code:

public class CachingRepository : IRepository
{
}

After couple minutes of investigation, I found that if code generation pop-up is invoked (Alt+Enter) there is an option Delegating members, but it is unavailable. So, I thought that maybe I should add to my class a field of interface type, which I want to decorate.

public class CachingRepository : IRepository
{
    private readonly IRepository repository;
}

After that step, the option Delegating members became available. Moreover, if caret position is on the class name and we press the shortcut for context actions (Ctrl+Enter), there is also an action Delegate implementation to ‘repository’ field available.

Visual Studio 2015, also offers quick actions, which are indicated by light bulb. We can invoke quick actions by using Ctrl+. shortcut. In earlier mentioned code snippet, if we put caret on interface name in type list of decorator, there would be actions offered by Visual Studio. One of the available fixes is Implement interface through ‘repository’, which produces the same results as the ReSharper code generation option.

More automation

I wondered why there is a requirement to include the field in class for the options to be available. After all, the field could be auto-generated. We can go even further and generate constructor with the decoratee as a parameter.

Let’s assume that we want to create a decorator around IRepository interface and we have:

public class CachingRepository : IRepository
{
}

Why can’t a tool do the work for us and generate following code?

public class CachingRepository : IRepository
{
    private readonly IRepository repository;

    public CachingRepository(IRepository repository)
    {
        if (repository == null)
        {
            throw new ArgumentNullException(nameof(repository));
         }
        this.repository = repository;
    }

    public void Save()
    {
        repository.Save();
    }

    public void Delete()
    {
        repository.Delete();
    }
}

Nowadays, thanks to Roslyn kind of task like that are much easier to implement. I thought about implementing it, but as I contribute to code-cracker project I came up with idea that this would be a good place to propose it as a new refactoring. Code-cracker is an analyzer library which provides helpful analysis and refactorings while you are writing C# (or VB) code. I created new issue in code-cracker project with details how the refactoring should work. Maybe someone else would be eager to implement it, unless I do it by myself.

Summary

I’m quite surprised, how the idea of adhering to the DRY principle turned into a contribution to the code-cracker project. In growing OSS world it is valuable to share your ideas because someone else might find it useful. We just need to find appropriate place where the idea could be used.



blog comments powered by Disqus

Published

30 October 2015

Tags