Using Extensions - Is It A Bad Design?

I just started looking at .NET 3.5, so please forgive me if you asked this question before. I struggle with the decent use of extension methods, in that I just downloaded the suteki shop to host MVC e-commerce. This project has a fairly standard repository template that extends IRepository.

To extend the basic functionality opened by this interface, ie extension methods are used:

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

Now everything is fine and good, but the interfaces, as far as I know, act like contracts for objects that implement them.

The fact that the repository was paired suggests an attempt at an agnostic approach to the data layer. However, if I created my own data layer, I would be confused as to what extension methods I would have to create to make sure I met the contract requirement that I have for classes that implement my repository classes.

It seems like an older way to create an IRepository and then an extension that allows you to see much better what is required, for example.

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

So, I think my question is, does using Extention methods seem wrong to anyone else? If not, why? Should I not moan about it?

EDIT:

The above example seems to be a good example of why extension methods can be very useful.

I believe that my problem is that certain features of data access implementation hovered in the extension method in the assembly of data access mechanisms.

Thus, if I changed it to another mechanism, I would have to create a similar extension method in this assembly.

+4
source share
4 answers

The fact is that if you implemented all IRepository<T> accordingly, you (as a data-level developer) should not know about root categories at all. As part of this extension method, it is assumed that any category repository will have a root category of identifier 1. This may well be a reasonable assumption and useful: no one should build a derived class (which may be impractical - there may be factories on the data layer, etc. ., because of which it is difficult to implement from implementations).

Now the extension method is applicable only if its scope is applicable - if it is in the namespace (or close relative), where this assumption about the root categories will be valid.

I don’t think that the "old" way would really be an interface extending IRepository<Category> - it would be a regular static method accepting IRepository<Category> . That extension methods just make life more enjoyable. If you really used inheritance instead, it is possible that it will now be worthwhile. Unfortunately, we do not know enough about the architecture of your system to say this for sure.

+5
source

The concept of extensions is just syntactic sugar, as some authors call it. This makes the code more readable, albeit less clear. Ultimately, extension methods are only static, which are a legacy of the procedural paradigm. They make the code tightly connected and less cohesive, more difficult to test and reuse.

I am inclined against this trend of the C # programming language. This function is attractive, but it does not bring any advantages, on the contrary, it increases the complexity of the code.

+4
source

This is not the same thing. The extension method is syntactic convenience, no more and, of course, not a contractual requirement. You do not "implement" them in your classes. For your example above:

 using CategoryRepositoryExtensions; ... Category c = r.GetRootCategory(); 

exactly the same as:

 Category c = CategoryRepositoryExtensions.GetRootCategory(r); 

and therefore, there is no additional requirement for an interface performer.

+1
source

Yes, in the example you mentioned, it seems inconsistent, and the reason is that you are working with one object at the same level. I find that extension methods are most useful when you are working with IQueryable / IEnumerable collections.

For example, consider two scenarios:

  • Scenario 1: Get a list of all orders containing product x

  • Scenario 2: get a list of all orders containing product x and sent to zipcode y

If you used a traditional / interface-oriented approach, you can determine that you are tempted to define two different interfaces. If you use extension methods, you can use something like the following

Scenario 1

 <IEnumerable> orders1Enumerable = OrderRepository.GetAllOrders() .ContainingProductCode(x); 

Scenario 2

 <IEnumerable> orders2Enumerable = OrderRepository.GetAllOrders() .ContainingProductCode(x) .WithShippingZipCode(y); 

When you do this, the environment creates the appropriate SQL on the fly, hooking these extension methods

Hope this helps

0
source

All Articles