8
votes

I am currently using IoC for providing concrete implemenations of repositories in a project. All of the examples that I have read use an interface as the definition of the service. However, having read recommendations from Microsoft it is recommended to prefer abstract classes over interfaces.

I have found this useful in conjuntion with the template pattern to reduce repetition. For example give a Product class with a property IsActive I could use an interface for the repository such as:

interface IProductRepository
{
    IEnumerable<Product> Load();
}

If a common task is to load active products then I would need to do:

IEnumerable<Product> activeProducts = repository.Load().Where(x => x.IsActive);

Where repository is a concrete implementation. If I used an abstract class such as:

abstract class ProductRepository
{
    protected abstract IEnumerable<Product> LoadCore();

    public IEnumerable<Product> Load()
    {
        return LoadCore().Where(x => x.IsActive);
    }
}

Then I could load active products using

IEnumerable<Product> activeProducts = repository.Load();

All the implementation for loading the product information is within the contrete class that derives ProductRepository so there is no coupling to the persistance layer. If it is found that there is another commonly performed activity then this could be added to the base class as a non-breaking change which could not be done using an interface.

Is there any benefit to using an interface instead of an abstract class? What potential drawbacks to using abstract classes could I come across?

I am using Castle Windsor as the IoC controller and .Net framework 3.5.

2

2 Answers

9
votes

I don't think this question hinges on IoC; most of these frameworks don't care which you use.

The big issue between using interfaces over abstract base classes is that interfaces cannot be versioned well.

Abstract base classes are usually the better choice because of this. I don't think there is any drawback to using an abstract base class, other than getting support questions like "why can't I create an instance of this type?"

2
votes

The recommendation comes from the Framework Design Guidelines. This recommendation of Microsoft exists specially for reusable class libraries. In other words: frameworks like the .NET framework itself. If you are creating a line of business application, this guideline does not apply. It does not apply because it is unlikely that you will have versioning problems in a line of business application, because you have control over all the client code that talks to your classes / interfaces. This is of course not the case for reusable libraries.

Even the article of Phil Haack, where Will references to describes this:

Again, these guidelines are specific to Framework development (for statically typed languages), and not to other types of software development.

Removing versioning problems is therefore probably not a good argument for using base classes. Keeping code DRY however could be. However, using base classes and interfaces aren't mutually exclusive; you can let your abstract class ProductRepository implement IProductRepository. If you do this however, exposing anything else than IProductRepository would be a bad idea.