项目中有很多存储库

时间:2014-10-17 09:05:41

标签: c# asp.net asp.net-mvc dependency-injection ninject

我正在使用ninject controller factory通过接口将一些存储库绑定到控制器......

public class NinjectControllerFactory : DefaultControllerFactory 
{
    private IKernel ninjectKernel;

    public NinjectControllerFactory() 
    {
        ninjectKernel = new StandardKernel();
        AddBindings();
    }

    protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType) {
        return controllerType == null ? null : (IController)ninjectKernel.Get(controllerType);
    }

    private void AddBindings() 
    {
        ninjectKernel.Bind<ISystemDefinition<CentreModel>>().To<CentreRepository>();
        ninjectKernel.Bind<ISystemDefinition<ResidentStatusModel>>().To<ResidentStatusRepository>();
    // here will be the list of lots of repositories with different models
    }

}

想象一下,我需要用不同的数据写出大约一百个表格,所以我需要至少有不同的模型......(可能有相同的&#34; IReposotory&#34;),但我仍然需要添加模型到&#34; AddBindings()&#34;方法......可以吗? (我不确定)...... 将具有不同模型的存储库存储到控制器中的最佳实践是什么?

模型例如:

public class CentreModel : BaseModel {
    [Required(ErrorMessage = "*")]
    [Display(Name = "Name:")]
    public string Name { get; set; }

    [Display(Name = "Order:")]
    [Required(ErrorMessage = "*")]
    public int SortOrder { get; set; }

    [Display(Name = "Is active:")]
    public bool IsActive { get; set; }

    [Required(ErrorMessage = "*")]
    [Display(Name = "Associated centre:")]
    public int AssociatedCentreId { get; set; }
    public IEnumerable<CentreListModel> OldCentres { get; set; }
}

接口示例:

public interface ISystemDefinition<T> where T : class,new()
{
    IEnumerable<T> GetList(bool? isActive = null);
    IEnumerable<T> GetList(bool? isActive = null, int? OwnerID = null);
    T Fetch(int? ID);
    void Save(T item);
    void Remove(T item);
    void Order(List<T> items);
}

和存储库示例:

public class CentreRepository : BaseRepository, ISystemDefinition<CentreModel> {
    public IEnumerable<CentreModel> GetList(bool? isActive) {
        return (from c in entities.Centres
                where c.IsActive == isActive || isActive == null
                orderby c.SortOrder
                select new CentreModel {
                    ID = c.ID,
                    Name = c.Name,
                    IsActive = c.IsActive,
                    SortOrder = c.SortOrder,
                    AssociatedCentreId = c.AssociatedCentreID
                });
    }

    public CentreModel Fetch(int? ID) {
        return (from c in entities.Centres
                where c.ID == ID
                orderby c.SortOrder
                select new CentreModel {
                    ID = c.ID,
                    Name = c.Name,
                    IsActive = c.IsActive,
                    SortOrder = c.SortOrder,
                    AssociatedCentreId = c.AssociatedCentreID
                }).FirstOrDefault();
    }

    public void Save(CentreModel model) {
        Centre centre = model.IsNew ? new Centre() : entities.Centres.Where(c => c.ID == model.ID).SingleOrDefault();

        centre.Name = model.Name;
        centre.SortOrder = model.SortOrder;
        centre.IsActive = model.IsActive;
        centre.AssociatedCentreID = model.AssociatedCentreId;

        if (model.IsNew) entities.Centres.Add(centre);

        Save();
    }

    public void Remove(CentreModel model) {
        Centre centre = model.IsNew ? new Centre() : entities.Centres.Where(c => c.ID == model.ID).SingleOrDefault();
        entities.Centres.Remove(centre);

        Save();
    }

    public void Order(List<CentreModel> items) {
        throw new NotImplementedException();
    }
    public IEnumerable<CentreModel> GetList(bool? isActive = null, int? OwnerID = null) {
        throw new NotImplementedException();
    }
}

1 个答案:

答案 0 :(得分:2)

不是为每个模型创建存储库,而是创建一个具体的通用存储库。

修改

例如,如果您有以下界面:

public interface IRepository<TEntity> : IDisposable where TEntity : class 
{
    IQueryable<TEntity> GetAll();
    IQueryable<TEntity> GetAllIncluding(params Expression<Func<TEntity, object>>[] includeProperties);
    TEntity Find(params object[] keys);
    void Add(TEntity entity, bool save = true);
    void Edit(TEntity entity, bool save = true);
    void Delete(bool save = true, params object[] keys);
    void Save();
}

您可以使用单个具体实现(示例使用EF):

public class Repository<TEntity> : IRepository<TEntity> where TEntity : class
{
    private readonly DbContext _context;

    public Repository(DbContext context)
    {
        if (context == null) throw new ArgumentNullException("context");
        _context = context;
    }

   public IQueryable<TEntity> GetAll()
   {
        return _context.Set<TEntity>();
   }

   public IQueryable<TEntity> GetAllIncluding(params Expression<Func<TEntity, object>>[] includeProperties)
   {
        IQueryable<TEntity> queryable = GetAll();
        return includeProperties.Aggregate(queryable, (current, includeProperty) => current.Include(includeProperty));
   }
public TEntity Find(params object[] keys)
   {
        return _context.Set<TEntity>().Find(keys);
   }
... etc. 
}

然后,您可以将开放的通用接口绑定到开放的通用存储库,如下所示:

Bind(typeof(IRepository<,>)).To(typeof(Repository<,>));

同样对于我的示例,您需要绑定要注入存储库构造函数的上下文:

Bind<DbContext>().To<MyDbContext>();

然后,这应该正确地为任何类型的模型实例化存储库,而不必为每个模型具有显式绑定。

所以使用下面的控制器构造函数:

protected readonly IRepository<SomeEntity> _repository;

protected BaseController(IRepository<SomeEntity> _repository)
{
    _repository = repository; 
}

Ninject会注入Repository<SomeEntity>