5

I have read a bit about constraints and am trying to implement it in my repository pattern.

I want something like the below but can't quite get it to compile.

 public interface IRepository<T>
 {
    void GetAllData<T>();
 }

 //This needs to inherit from IRepository
 //T has to be a model class
 //V has to be a class that implements IEmployeeRepo
 public interface IEmployeeRepo<T, V> where V : EmployeeRepo where T : class : IRepository<T>
 {
    void DoSomethingEmployeeRelated();
 }

 //Dont think this inheritance is correct
 public class EmployeeRepo<Employee, this> : IEmployeeRepo
 {


 }

 //My example model class
 public class Employee
 {
     public string Name {get;set;}
 }
2
  • There are far too many errors in your code (I can spot 3 at least) to understand what you want. Commented Jan 24, 2011 at 11:34
  • Read the notes above IEmployeeRepo and I also mentioned it will not compile Commented Jan 24, 2011 at 11:35

3 Answers 3

17

Not sure why you have two type parameters on the Repository - what is the point?

*Here is the classic example of a .NET Repository using Generics: *

*First, the Repository Interface: *

public interface IRepository<T> where T : class
{
   T FindSingle(Expression<Func<T,bool>> predicate);
   IQueryable<T> FindAll(); // optional - matter of preference
   void Add(T entity);
   void Remove(T entity);
}

*Second, the Generic Repository Implementation (EF as the example): *

public abstract class GenericRepository<T> : IRepository<T>
{
   private IObjectSet<T> _ObjectSet; // get this in via DI (for example)

   public T FindSingle(Expression<T,bool>> predicate)
   {
      return _ObjectSet.SingleOrDefault(predicate);
   }

   // you can figure out how to do the other implementation methods
}

*Then, the Specific Repository (you should have one per aggregate root, and also an interface for each specific repository detailing specific methods): *

public EmployeeRepository : GenericRepository<Employee>, IRepository<Employee>
{
   // all regular methods (Find, Add, Remove) inherited - make use of them
   public Employee FindEmployeeByName(string name)
   {
      return FindAll().SingleOrDefault(x => x.Name == name);
      // or you could do: return FindSingle(x => x.Name == name);    
   }
}

Usage:

IRepository<Employee> repository = new EmployeeRepository<Employee>();

Don't go out looking to go too crazy with generics - the only one you need is to constrain the Repository to be used by a entity that is encapsulated behind the Repository.

I simply use where T : class.

Other's use where T : IDomainAggregate or similar, to put constraints on the actual type of entity which is allowed.

Sign up to request clarification or add additional context in comments.

1 Comment

Can I ask did you get this documentation from somewhere or did you write it?
5

In this situation i usually have a base repo class that implements IRepository<>, and is typed to a base Model class.

public interface IRepository<T> where T : IModel
 {
    void GetAll<T>();
    void GetById<T>(int id);
 }    

 public interface IEmployeeRepo<T> : IRepository<T> where T : IModel
 {
    void DoSomethingEmployeeRelated();
 }

 public class BaseRepo : IRepository<T> where T : IModel
 {

    public void GetAll<T>()
    {

    }

    public void GetById<T>(int id)
    {

    }
 }


 public class EmployeeRepo : BaseRepo<Employee>,  IEmployeeRepo<Employee>
 {
    public void DoSomethingEmployeeRelated()
    {

    }

 }

 //My example model class
 public class Employee : IModel
 {
     public int Id {get;set;}
     public string Name {get;set;}
 }

Comments

1

Try this;

public interface IRepository<T>
 {
    void GetAllData<T>();
 }

 //This needs to inherit from IRepository
 //T has to be a model class
 //V has to be a class that implements IEmployeeRepo
 public interface IEmployeeRepo<T, V> : IRepository<T> where V : EmployeeRepo where T : class
 {
    void DoSomethingEmployeeRelated();
 }

 //Dont think this inheritance is correct
 public class EmployeeRepo : IEmployeeRepo<Employee, EmployeeRepo>
 {
    public void DoSomethingEmployeeRelated()
    {

    }

    public void GetAllData<Employee>()
    {

    }
 }

 //My example model class
 public class Employee
 {
     public string Name {get;set;}
 }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.