ReSharper hidden features – Generate Delegating Members

A frequently-used design pattern is the Decorator. This is also known as a mixin (or they might not be the very same thing but certainly they are related).

Typically you might need to create a class that implements a certain interface and uses another class that implements that exact interface but you need to provide some additional feature(s). An example would be a class that adds transactional behavior to an existing data-access class (a naive example) :


public interface IDataAccess
{
    void AddCustomerInvoice(Invoice invoice, User user);
}

public class DataAccess : IDataAccess
{
    public void AddCustomerInvoice(Invoice invoice, User user)
    {
        InsertInvoice(invoice, user);
        UpdateCustomerDebt(user, invoice.Total);
    }

    // ... the rest of the implementation
}

public class TransactionalDataAccess : IDataAccess
{
    private readonly IDataAccess _dataAccess;

    public TransactionalDataAccess(IDataAccess dataAccess)
    {
        if (dataAccess == null)
        {
            throw new ArgumentNullException();
        }
        _dataAccess = dataAccess;
    }

    public void AddCustomerInvoice(Invoice invoice, User user)
    {
         using(var tx = new TransactionScope())
         {
             _dataAccess.AddCustomerInvoice(invoice, user);
             tx.Complete();
         }
    }

    // ... the rest of the implementation
}

Another type of example would be the Adapter design pattern. An example would be providing access to a (static) class (that may be out of your control) in a mock-able manner. That is, implement another class, non-static, which implements a defined interface and eases unit-testing :


public class StorageManager
{
    public void StoreData(string key, byte[] data)
    {
         if (string.IsNullOrWhiteSpace(key))
         {
              throw new ArgumentNullException("key");
         }
         if (data == null)
         {
             throw new ArgumentNullException("data");
         }
         System.IO.File.WriteAllBytes(key + ".bin", data);
    }
}

This class, as you can see, uses the static File class in the BCL of .NET Framework. If I need to unit-test the StoreData method in a way to assert that the data is actually written to the file (and maybe test the file is named as the key and the binary data and only the binary data is placed in that file etc.) then I can’t do it. Well you might get away with TypeMock Isolator (expensive piece of… software) or Moles/Pex but it’s just not right™.

So we define an interface :


public interface IFileAccess
{
    void WriteAllBytes(string filePath, byte[] binaryContent);
}

and then we write an implementation for this class


public class FileAccessAdapter : IFileAccess
{
    public void WriteAllBytes(string filePath, byte[] binaryContent)
    {
        System.IO.File.WriteAllBytes(filePath, binaryContent);
    }
}

Finally we update the StorageManager class :


public class StorageManager
{
    private readonly IFileAccess _fileAccess;

    public StorageManager(IFileAccess fileAccess)
    {
         if (fileAccess == null)
         {
             throw new ArgumentNullException("fileAccess");
         }
         _fileAccess = fileAccess;
    }

    public void StoreData(string key, byte[] data)
    {
         if (string.IsNullOrWhiteSpace(key))
         {
              throw new ArgumentNullException("key");
         }
         if (data == null)
         {
             throw new ArgumentNullException("data");
         }
         _fileAccess.WriteAllBytes(key + ".bin", data);
    }
}

Now we can unit test the StorageManager class by providing a mock of the IFileAccess interface.

Having finished the introduction let’s get to business. The nice thing is that using these patterns you have a more loosely-coupled code and you can unit test it. The not-so-nice thing is that you need to write a lot of repetitive code that’s really boring. I mean usually the interfaces won’t have 1-2 methods like my examples above but sometimes tens or even a hundred (yes, unfortunately some people haven’t heard of ISP – Interface Segregation Principle).

Today, as I was creating such an adapter for a static class to which I don’t have much control, I thought : maybe ReSharper can help me… I looked in the implement interface dialog box but no help. Then I turned to Google and as usual in the past few years one of the best piece of information came from Stackoverflow : How to (visual studio 2008 / Resharper) refactor / automate mixin pattern.

Trying to implement the adapter pattern I failed since ReSharper does not support this scenario directly but being intrigued I tried to create a decorator (the first scenario presented above). However, let’s resume the first example. At first I wrote the class definition and the constructor for the TransactionalDataAccess class :


public class TransactionalDataAccess : IDataAccess
{
    private readonly IDataAccess _dataAccess;

    public TransactionalDataAccess(IDataAccess dataAccess)
    {
        if (dataAccess == null)
        {
            throw new ArgumentNullException();
        }
        _dataAccess = dataAccess;
    }
}

Then I pressed ALT-INSERT inside the block of code of the class :

I selected Delegating members and then in the following dialog box :

I selected all the interface’s members (in this simple example there was only one but in production I selected around 50 members). Finally the code generated was like this :


public class TransactionalDataAccess : IDataAccess
{
    private readonly IDataAccess _dataAccess;

    public TransactionalDataAccess(IDataAccess dataAccess)
    {
        if (dataAccess == null)
        {
            throw new ArgumentNullException();
        }
        _dataAccess = dataAccess;
    }

    public void AddCustomerInvoice(Invoice invoice, User user)
    {
        _dataAccess.AddCustomerInvoice(invoice, user);
    }
}

I just added the transaction wrapper :


public class TransactionalDataAccess : IDataAccess
{
    private readonly IDataAccess _dataAccess;

    public TransactionalDataAccess(IDataAccess dataAccess)
    {
        if (dataAccess == null)
        {
            throw new ArgumentNullException();
        }
        _dataAccess = dataAccess;
    }

    public void AddCustomerInvoice(Invoice invoice, User user)
    {
        using (var tx = new TransactionScope())
        {
            _dataAccess.AddCustomerInvoice(invoice, user);
            tx.Complete();
        }
    }
}

… and I was done with it. For the adapter class all you need is to extract the interface from the static class (you can view the metadata using Visual Studio and copy/paste it). Then create the adapter class, create a constructor with (at least) one parameter of the interface type, generate the delegating members just like above, modify or delete the constructor and the private field and replace (CTRL-H) all the occurences of the private field with a call to the static class being adapted.

… that’s all folks!

  1. Interesting .NET Links - July 30 , 2012 | TechBlog - pingback on 4 May 2014 at 20:05

Leave a Comment


NOTE - You can use these HTML tags and attributes:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Trackbacks and Pingbacks: