Search code examples
c#cqrscomposition

How to choose between adding an interface and adding an attribute


In our project we are using a CQS pattern. Because some of our queries call other webservices, which in our case can be slow, we want to cache those results. Now I've found several solutions how to do this:

  1. Create an CachedQuery which inherits from a Query object.
  2. Add a 'CacheResult' attribute to the queryhandler, have a decorator check for the presence of this attribute
  3. Add a 'CacheResult' attribute to the query, have a decorator check for the presence of this attribute
  4. Implement a 'ICacheableQuery' interface, have a decorator check for the implementation of this interface.

option 1 is discarded because of "composition over inheritance'

option 2 is not really flexible, e.g. it is not possible to not cache

But how to choose between 3 and 4? Adding an attribute is not inheritance (or is it?) so that is equal. Both are flexible enough, at least for now.

Do I miss some convincing argument? Or is it a matter of personal preference, if so what would you choose to do?


Solution

  • Adding an attribute is not inheritance (or is it?)

    Whether you want your custom attribute to be inherited is up to you to implement. When you write code that checks the presence of an attribute, you can write it so that it checks the base classes/interfaces for the attribute as well.

    As a commenter already noted, attributes allow you to add metadata that could be useful depending on what you're trying to implement.

    Generally, I dislike having interfaces without methods just for the sake of differentiating types. But in the end...

    Is it a matter of personal preference

    Yes.