Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Extension methods usage - Isn't this bad design?

I have just started to look at .NET 3.5 so please forgive me if this type of question have been asked before. I am struggling with a decent usage for extension methods, in that I have just downloaded suteki shop an MVC ecommerce offering. In this project there is a pretty standard Repository pattern that extends IRepository.

In order to extend the basic functionality exposed by this interface, extention methods are used i.e.:

public static class CategoryRepositoryExtensions
{
    public static Category GetRootCategory(this IRepository<Category> categoryRepository)
    {
     return categoryRepository.GetById(1);
    }
}

Now this is all well and good, but Interfaces, as far as I am concerned act as contracts to the objects that implement them.

The fact that the repository has been interfaced out suggests an attempt at a data layer agnostic approach. That said, if I were to create my own data layer I would be confused as to what extension methods I would have to create to ensure I have fulfilled the contractual requirement I have to the classes that implement my repository classes.

It seems that the older way of creating an IRepository and then extending that allows a much better visibility of what is required e.g.

ICategoryRepoitory : IRepository<Category>
{
     Category GetRootCategory();
}

So I guess my question is does this use of Extention methods seem wrong to anyone else? If not, why? Should I not be moaning about this?

EDIT:

The above example does seem to be a good example of why extention methods can be very helpful.

I suppose my issue is if data access specific implementations were stuck in the extention method in the data access mechanisms assembly.

That way if I were to swap it out for another mechanism I would have to create a similar extention method in that assembly.

like image 444
Owen Avatar asked Dec 30 '22 08:12

Owen


1 Answers

The point is that if you've implemented all of IRepository<T> appropriately, you (as the data layer implementor) don't have to know about root categories at all. For the scope of this extension method, it is assumed that any repository of categories will have a root category of ID 1. That may well be a perfectly reasonable assumption, and a useful one: no-one has to build a derived class (which may well be impractical - the data layer may have factories etc which make it tricky to derive from the implementations).

Now, the extension method is only applicable if its scope is appropriate - if it's in a namespace (or closely related one) where that assumption about root categories will be valid.

I don't think the "older" way would really be an interface extending IRepository<Category> - it would be a normal static method taking IRepository<Category>. That's where extension methods just make life more pleasant. If you really would have used inheritance instead, it may well be appropriate to do so now as well. Unfortunately we don't know enough about the architecture of your system to say that for sure.

like image 107
Jon Skeet Avatar answered Jan 04 '23 22:01

Jon Skeet