RepositoryBase, RepositoryQueryable and a lot of code duplication

38 views
Skip to first unread message

xvd...@gmail.com

unread,
Sep 22, 2014, 6:24:29 AM9/22/14
to sharpre...@googlegroups.com
While browsing through the SharpRepository source I noticed that there's a lot of duplicated code on the interfaces, mostly because of the a bit unfortunately designed traits.

For example the 'ICanDelete<T, in T>' trait exposes a delete-by-key method, hence (as it is stated in a comment) it can't be used in 'IRepositoryBase<T>'. Then we got a 'ICrudRepository<T, T>' which is basically 'IRepository<T, T>' except without query methods.

My suggestions to overcome this design issue:

# Splitting up traits

Technically, the traits could be split up to a even more fine-granulared level in order to re-use them in the desired places. E.g.

public interface ICanDelete<T> {

void Delete(T entity);

}

public interface ICanDelete<T, TKey> :
ICanDelete<T>
{

void Delete(TKey key);

}

This would also be applyable for the compound key repositories. A major drawback might be that we end up with like 40 different, often meaning-less traits, which can be a pain for maintenance.

# Dropping traits

While I'm absolutely in for the SRP, it can cause sometimes a real PITA. As the repository pattern becoming more and more just an abstraction over the top of a ORM framework, it should be considered dropping the traits completely in favor of simplicity. I know there's still a difference between the repository and a ORM object context, however this is only valid if we use the repository pattern completely by exposing meaningfull interfaces that follow the ubiquitous language, which is not possible with stuff like 'Generic Repositories' that also support batching, caching, mapping and what not. So what's left? As I said before: Just a clean approach to abstract away the quirks of a ORM with the possibility to swap out an entire framework.

One should be able to make a 'All-In-One' repository which can then be used along with the adapter pattern and DI like this:

public UserRepository : IUserRepository {

private readonly IGenericRepository<User> _genericRepo;

protected UserRepository(IGenericRepository<User> genericRepo) {
_genericRepo = genericRepo;
}

// intention-telling interface!
public User FindOldestUser() {
return _genericRepo.Find.... //
}

}

What do you guys think?

Jeff Treuting

unread,
Sep 29, 2014, 11:51:29 PM9/29/14
to xvd...@gmail.com, sharpre...@googlegroups.com
You are right that there is duplicate code in more than just the parts that you mentioned. Finding the time to do cleanup is the major stumbling block when it comes to that.

As far as the UserRepository example you give, I believe you can accomplish that with today's library in a couple ways.

First, you can inherit from ConfigurationBasedRepository, like so:

public UserRepository : ConfigurationBasedRepository<User>, IUserRepository {

// intention-telling interface!
public User FindOldestUser() {
return Repository.Find(...);
}

}

Or you could pass in a repository just like you are doing in the example you provided.

The idea behind SharpRepository is to give that generic repository to allow caching and configuration based changes to switch between the data stores that back the repository. Sometimes it is a good fit for a project and sometimes it isn't, it all depends on the situation.

Jeff
--
You received this message because you are subscribed to the Google Groups "SharpRepository" group.
To unsubscribe from this group and stop receiving emails from it, send an email to sharpreposito...@googlegroups.com.
To post to this group, send email to sharpre...@googlegroups.com.
Visit this group at http://groups.google.com/group/sharprepository.
To view this discussion on the web visit https://groups.google.com/d/msgid/sharprepository/26a95228-8884-4a51-8303-40b063f17b85%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Reply all
Reply to author
Forward
0 new messages