2012-04-04 2 views
1

Я новичок в концепции Репозитория и задаю некоторые вопросы. Я создал простой класс репозитория в моем приложении MVC.Концепция IRepository, где создавать определенные репозитории

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 
    } 

В моем контроллере я инициализировать классы хранилища для указанного класса таблицы, как этот

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 
} 

Но я дублировать этот код снова и снова во многих местах в моем приложении. Какое лучшее место для экземпляра этих классов репозитория?

+0

Использовать фабрику ... – mshsayem

+0

Почему бы не создать в своем SqlRepository конструктор с меньшим значением конструктора? – Peter

ответ

4

Я думаю, вам следует обратиться к хранилищу через его интерфейс:

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 
} 

И вводят реализации через некоторые инъекции зависимостей структуры.

UPDATE

Вы можете использовать Ninject для инъекций зависимостей для контроллеров. Вот Example как добавить DependencyResolver в ваше приложение. В вашем случае вы можете настроить ядро ​​таким образом:

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<>)); 

И все. Нет дублирования. Зависимости разрешены. Ваш класс не зависит от конкретных репозиториев. Вы можете легко обманывать зависимости для тестирования.

+0

Не могли бы вы объяснить, почему я должен обращаться через интерфейс? – Tomas

+1

Настоятельно рекомендуется впрыскивать эти зависимости. Если каждый контроллер создает собственный репозиторий, вы теряете все преимущества, связанные с наличием единого хранилища (кэширование и т. Д.). –

+2

@ Томас, вы всегда должны стараться, где это возможно, кодировать интерфейс (абстракцию), потому что таким образом приложение не будет связано с конкретной реализацией. Позже вы можете переключиться на использование файлов xml в качестве хранилища или даже хранилище clould, и вы хотите, чтобы изменения не повлияли на остальную часть приложения. Другое использование - это тестирование. Легче протестировать ваши контроллеры или любой код с помощью репо, поскольку вы можете издеваться над репо или использовать поддельную реализацию репо – MikeSW

Смежные вопросы