Posted by: horizonguy | July 3, 2010

Repository Implementation in C#

There are a few repository implementations out there in C#. Rhino Commons and S#harp Architecture, among some other one listed on codeplex.

I’ve got my own as well that is part of the CommonLibrary.NET. See the repository example here http://commonlibrarynet.codeplex.com/documentation.

3 Mistakes with Repository Implementations

1. Non-Generic CRUD names

Approach 1
public class BlogPostRepository
{
public void CreateBlogPost(Post post)...
public void UpdateBlogPost(Post post)...
public void DeleteBlogPost(Post post)
....
}

instead of
Approach 2
public class BlogPostRepository : IRepository(Post)
{
public void Create(Post post)...
public void Update(Post post)...
public void Delete(Post post)
....
}

Now the 2nd approach is much better and has the following benefits:

  • Simpler
  • Allows you to extend from a common IRepository class that contains generics based Create,Update,Delete and other methods.
  • Provides for more consistency. All your repositories look and behave the same.
  • Allows for dynamically creating entities without knowing the type. What I mean by this is that you can populate either a Post or Event object( both of which have their own repositories ) and through some reflection, you can call .Create on the appropriate repository

Further improvement

Create your repository to be even more generic

public class Repository<T> where T: class
{
public void Delete(int id)…

public void Get(int id)…

….
}

 

public class BlogPostRepository : Repository<BlogPost>

{

public void Create(T entity)…
public void Update(T entity)…

}

2. Not using a IQuery for flexible queries

The second method involves having multiple FindXXX methods.

Approach 1


public IList(Event) FindByNameAndGroup( string eventName, string group )...

public IList(Event) FindByOwner( string owner )...

 

This can easily get out hand.
Instead the following can be done:
Approach 2


public IList(Event) Find( Query query )...

// The caller would use it like so.
public static void main(string[] args)
{
...
repository.Find( Query.New().Where( e => e.Name ).Is( "asp.net" ).And( e => e.Group ).Is( "web" );
}

Now the second approach will let you handle many different queries. In this example, I’m using a combination of Expression Tree’s and Fluent API to get the Query syntax. This approach is used in the CommonLibrary.net Repository implementation. You can also create helper methods above the repository layer as in example 1 and then delegate to the repo.Find(Query) method on the repository instead of creating multiple FindXXX methods in the repository.

Note: You can also use C#’s Expression Tree purely to accomplish the same effect, for example in Entity Frameworks Find(Expression exp ) methods.

One step further

Now with C# 4.0 dynamic and Expando Object. You can possibly build dynamic find/search method using a ruby rails like style.

e.g.

repo.FindByNameAndOwner(“asp.net”, “kishore”);

where:

1. FindByNameAndOwner is a dynamic method on an expando object.

2. You get the fields to search for using the name of the method ( Name, and Owner) and use the parameters for those variables.

3. You get the condition from the name of the method. ( “NameAndOwner” )

 

3. Audit fields

Finally, the last problem that I see, is that each entity that is persisted by a repository should have the following audit fields.

  1. Id
  2. CreatedBy
  3. UpdatedBy
  4. CreateDate
  5. UpdateDate
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Categories

%d bloggers like this: