Base fluent repository

by andrei 15. November 2008 01:39

In some previous posts (here and here) I was describing some ideas related to fluent repositories.

 

Here is an idea to bring some of that functionality into a base repository, and obtain less repetitive code:

public class BaseRepository<EntityType, PKType, RepositoryType> where RepositoryType : class
{
  protected ICriteria _criteria;

  protected ISession Session
  {
    get
    {
      return SessionHolder.Current;
    }
  }

  public RepositoryType InitialiseCriteriaFor ( PKType id )
  {
    InitialiseCriteria();
    _criteria.Add(Restrictions.Eq("Id", id));

    return this as RepositoryType;
  }

  public RepositoryType InitialiseCriteria ( )
  {
    return InitialiseCriteria("");
  }

  public virtual RepositoryType InitialiseCriteria ( string alias )
  {
    if (IEnumerableExtensions.IsEmpty(alias))
      _criteria = Session.CreateCriteria(typeof(EntityType));
    else
    {
      _criteria = Session.CreateCriteria(typeof(EntityType), alias);
    }
    return this as RepositoryType;
  }

  private BaseRepository<EntityType, PKType, RepositoryType> OnlyActive ( )
  {
    IActivable activable = this as IActivable;

    if (activable == null) return this;

    _criteria.Add(Restrictions.Eq(activable.IsActiveField, true));
    return this;
  }

  private BaseRepository<EntityType, PKType, RepositoryType> Sorted ( )
  {
    ISortable sortable = this as ISortable;

    if (sortable == null) return this;

    _criteria.AddOrder(new Order(sortable.SortField, sortable.Ascending));
    return this;
  }

  public RepositoryType InitialiseListCriteria ( )
  {
    InitialiseCriteria();

    return OnlyActive().Sorted() as RepositoryType;
  }

  public EntityType LoadEntity ( )
  {
    return _criteria.UniqueResult<EntityType>();
  }

  public IList<EntityType> LoadList ( )
  {
    return _criteria.List<EntityType>();
  }

  public ICriteria GetCurrentCriteria ( )
  {
    return _criteria;
  }

  public RepositoryType ByIds ( IEnumerable<PKType> ids )
  {
    _criteria.Add(Restrictions.In("Id", (ICollection)ids));

    return this as RepositoryType;
  }

  public RepositoryType MaxResults ( int maxResults )
  {
    _criteria.SetMaxResults(maxResults);
    return this as RepositoryType;
  }

  public virtual bool Ascending
  {
    get
    {
      return true;
    }
  }
}

 

The generic signature contains the type of the repository, but the same result could be obtained with reflection and the parameter would dissapear. I am also using 2 sample interfaces, which bring default sorting and filtering behavior into the BaseRepository:

public interface ISortable
{
  string SortField { get; }
  bool Ascending { get; }
}
public interface IActivable
{
  string IsActiveField { get; }
}

 

Here is how a simple repository would look:

public class TagRepository: BaseRepository<Tag, int, TagRepository>, ISortable
{
  public TagRepository ByTagNames(IList<string> tags)
  {
    _criteria.Add(Restrictions.InG("TagName", tags));
    return this;
  }

  public string SortField
  {
    get { return "TagCount"; }
  }
}

 

and here is how it can be used:

IList<Tag> existingTags = _tagRepository.InitialiseListCriteria().ByTagNames(crtTagNames).LoadList();

This will load all tags which have a name from the given list, and sort them by TagCount.

 

The BaseRepository above contains a few more options, and others can easily be added.

 

 

Enjoy programming!

 

DDD

I am putting together a set of concept lists for the main programming techniques, which should help developers learning or using them to be more efficient. Here are the techniques in progress:

Please feel free to leave any comments or suggestions which could make these lists more useful for everyone.

 

 

Also, if you are interested in learning these techniques you can try the developer training modules.

Again, please feel free to leave any comments or suggestions which could make the training modules more useful for everyone. We are having great results with them at Akcedo (so they really work), but they can always be improved. Also, if you would like to use the modules or are already using them and you want to discuss about the process feel free to comment and ask questions here.

Add comment


(Will show your Gravatar icon)  

  Country flag

biuquote
  • Comment
  • Preview
Loading



Powered by BlogEngine.NET 1.4.5.0