IRepository concept, where to create specified repositories

Go To StackoverFlow.com

1

I am new to Repository concept and get some questions. I have created simple repository class in my MVC app.

   public interface IRepository<TEntity> where TEntity : class
    {
        List<TEntity> FetchAll();
        IQueryable<TEntity> Query { get; }
        void Add(TEntity entity);
        void Delete(TEntity entity);
        void Save();
    }

    public class SqlRepository<T> : IRepository<T> where T : class
    {
        readonly DataContext _db;
        public SqlRepository(DataContext db)
        {
            _db = db;
        }

        #region IRepository<T> Members

        public IQueryable<T> Query
        {
            get { return _db.GetTable<T>(); }
        }

        public List<T> FetchAll()
        {
            return Query.ToList();
        }

        public void Add(T entity)
        {
            _db.GetTable<T>().InsertOnSubmit(entity);
        }

        public void Delete(T entity)
        {
            _db.GetTable<T>().DeleteOnSubmit(entity);
        }

        public void Save()
        {
            _db.SubmitChanges();
        }

        #endregion
    }

In my Controller I initialize repository classes for specified table class like this

 public class AdminController : Controller
    {

        private readonly SqlRepository<User> _userRepository = new SqlRepository<User>(new DataContext(ConfigurationManager.ConnectionStrings["ConnectionString"].ToString()));
        private readonly SqlRepository<Order> _orderRepository = new SqlRepository<Order>(new DataContext(ConfigurationManager.ConnectionStrings["ConnectionString"].ToString()));        

//Skip code
}

But I duplicate this code again and again in many places in my app. What is the best place to instanceate these repository classes?

2012-04-04 07:57
by Tomas
Use a factory.. - mshsayem 2012-04-04 08:01
Why not create a parameter less constructor in your SqlRepository that does this - Peter 2012-04-04 08:03


4

I think you should refer to repository via it's interface:

public class AdminController : Controller
{
   private readonly IRepository<User> _userRepository;
   private readonly IRepository<Order> _orderRepository;

   public AdminController(IRepository<User> userRepository, 
                          IRepository<Order> orderRepository)
   {
       _userRepository = userRepository;
       _orderRepository = orderRepository;
   }
   //Skip code
}

And inject implementations via some dependency injection framework.

UPDATE

You can use Ninject for dependency injection to your controllers. Here is Example how to add DependencyResolver to your application. In your case you can configure kernel this way:

IKernel kernel = new StandardKernel();
var connectionString = ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;
kernel.Bind(typeof(DataContext)).ToMethod(context => new DataContext(connectionString));
kernel.Bind(typeof(IRepository<>)).To(typeof(SqlRepository<>));

And that's it. No duplication. Dependencies are resolved. Your class does not depend on concrete repositories. You can easy mock dependencies for testing.

2012-04-04 08:01
by Sergey Berezovskiy
Could you explain why I should refer via interface - Tomas 2012-04-04 08:16
Injection of these dependencies is highly recommended. If each controller creates it's own repository, you loose all the advantages that come with having single repository (caching etc.) - Erik Philips 2012-04-04 08:32
@Tomas, you should always try where possible to code against an interface (an abstraction) because that way, the app won't be coupled to a specific implementation. Later you might want to switch to using xml files as storage or even clould storage and you want the change to not affect the rest of the app. Another usage is that you for testing. It's easier to test your controllers or any code using the repo as you can mock the repo or use a fake repo implementatio - MikeSW 2012-04-04 08:39
Ads