【问题标题】:C# MVC repository inheritance and common dataContextC# MVC 存储库继承和通用 dataContext
【发布时间】:2011-07-19 10:36:30
【问题描述】:

假设我有一个 GenericRepository:

public class IGenericRepository 
{
     // bla bla bla
}

public class GenericRepository : IGenericRepository
{
     public myDataContext dc = new myDataContext(); 

     // bla bla bla
}

我有一个特定的类别存储库:

public class CategoryRepository : GenericRepository
{
     // bla bla bla
}

在我的控制器中:

public ActionResult something() 
{
     CategoryRepository cr = new CategoryRepository();
     GenericRepository gr = new GenericRepository();
     Category cat = cr.GetMostUsedCategory();
     SubCategory sub = gr.GetById(15); 

     // And after I make some changes on these two entities I have to:

     cr.Save();
     gr.Save();
}

现在,是否可以使用适用于所有存储库的通用数据上下文?这样当我从gr.Save() 保存时,它将申请cr?我的意思是:

//Instead of  
cr.Save();
gr.Save();

//I want
gr.Save(); // And my category will also be saved.

这可能吗?

【问题讨论】:

    标签: c# model-view-controller inheritance repository datacontext


    【解决方案1】:

    你能做这样的事情吗? (将您的派生存储库传递给泛型)

    public class IGenericRepository 
    {
       void Save();
    }
    
    public class GenericRepository : IGenericRepository
    {     
        public myDataContext dc = new myDataContext(); 
        private _IGenericRepository = null;
    
       // bla bla bla
    
        public GenericRepository(IGenericRepository repository)
        {
            _IGenericRepository = repository;
        }
    
        void Save()
        {
           _IGenericRepository.Save();
        }         
    }
    

    【讨论】:

      【解决方案2】:

      IGenericRepository 包含你的保存方法?

      public class IGenericRepository 
      {
           save{};
      }
      

      【讨论】:

        【解决方案3】:

        在您的情况下,鉴于 CategoryRepository 从 GenericRepository 继承,为什么不将 CategoryRepository 用于两个调用并因此使用相同的上下文。但是最好的方法是通过 DI 容器注入上下文,并使用容器的 LifetimeManager 来确保整个 HttpRequest 都可以使用相同的上下文。

        如果你碰巧在使用微软的 Unity,我写了一篇关于它的博文here

        【讨论】:

        • 嗯,你是对的,对于这个例子我可以做到,但在某些情况下我必须使用不同的特定存储库,所以我应该在那里做什么?
        • 如果相同的上下文被注入到两个存储库中调用 Save 将导致所需的行为。然而,通过接口抽象上下文,这种模式(工作单元)变得更加明确。然后,您的控制器还将依赖此接口并决定何时调用 Save。由于此接口解析为传递给两个存储库的上下文,因此您将实现所需的行为。
        【解决方案4】:

        您可以将Unit Of work 模式用于这些目的。

        【讨论】:

          【解决方案5】:

          您应该为 DataContext 概念再添加一层抽象:

          //It is the generic datacontext
          public interface IDataContext
          {
              void Save();
          }
          
          //It is an implementation of the datacontext. You will
          //have one of this class per datacontext
          public class MyDataContext:IDataContext
          {
              private DataContext _datacontext;
              public MyDataContext(DataContext dataContext)
              {
                  _datacontext = dataContext;
              }
          
              public void Save()
              {
                  _datacontext.Save();
              }
          }
          

          然后在您的存储库中:

          public class GenericRepository<TDataContext> : IGenericRepository where TDataContext: IDataContext,new()
          {
              public TDataContext dc = new TDataContext();
          
              // bla bla bla
          }
          
          public class CategoryRepository:GenericRepository<MyDataContext>
          {
              // bla bla bla
              public void SaveSomething()
              {
                  dc.Save();
              }
          }
          

          当然,这只是一种方法 :-) 你可以改进它,但重点是抽象 Datacontext 的概念。您可以将您的代码用于任何数据上下文(甚至是NHibernate)。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2012-08-16
            • 1970-01-01
            • 2011-09-15
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多