1

次の実装があるとします。

//Generic repository.
public interface IRepository<T> where T : class {
   void Insert(T entity);
   void Delete(int id);
   void SaveChanges();
   //..more generic functions
}

//Repository implementation.
public class EFRepository<T> : IRepository<T> where T: class {
   private MyDbContext context;
   protected DbSet<T> dbSet;

   public EFRepository(): this(new MyDbContext()){}

   public EFRepository(MyDbContext context)
   {
      this.context = context;
      dbSet = context.Set<T>();
   }

   public void Insert(T entity)
   {
      dbSet.Add(entity);
   }

   public void Delete(int id)
   {
      dbSet.Remove(dbSet.Find(id));
   }

   public void SaveChanges()
   {
      context.SaveChanges();
   }
   //...more generic implementations
}

//Unit of Work Interface
public interface IUnitOfWork: IDisposable
{
   IRepository<EntityA> ARepository { get; }
   IRepository<EntityB> BRepository { get; }
   //...more stuff
}

//Unit of Work Implementation
public class EFUnitOfWork: IUnitOfWork
{
   private MyDbContext context = new MyDbContext();

   private IRepository<EntityA> aRepository;
   private IRepository<EntityB> bRepository;

   public IRepository<EntityA> ARepository 
   {
      get
      {
            if (this.aRepository == null)
               this.aRepository = new EFRepository<EntityA>(context);

            return this.aRepository;
      }

   }

   public IRepository<EntityB> BRepository 
   {
      get
      {
            if (this.bRepository == null)
               this.bRepository = new EFRepository<EntityB>(context);

            return this.bRepository;
      }

   }

   //...more stuff
}

最後に、リゾルバーに次のバインディングがあります。

kernel.Bind(typeof(IRepository<>)).To(typeof(EFRepository<>));
kernel.Bind(typeof(IUnitOfWork)).To(typeof(EFUnitOfWork));

さて、私の質問は... EntityA のリポジトリを拡張して、一般的な操作よりも多くの操作を行うにはどうすればよいでしょうか?

今までの内容を少しずつ載せていきます...

編集:これが私がこれまでに持っているものです:

//New interface.
public class IEntityARepository : IRepository<EntityA>
{
   void DoSomethingSpecificToEntityA();
}

//New implementation.
public class EFEntityARepository : EFRepository<EntityA>
{
   public EFEntityARepository(MyDbContext context) : base(context) {}
   //add additional methods for EntityA
   public void DoSomethingSpecificToEntityA()
   {

   }

}


//Modify Unit of Work Interface as follows.
//Unit of Work Interface
public interface IUnitOfWork: IDisposable
{
   IEntityARepository  ARepository { get; }
   IRepository<EntityB> BRepository { get; }
   //...more stuff
}

//Modify Unit of Work Implementation as follows.
public class EFUnitOfWork: IUnitOfWork
{
   private MyDbContext context = new MyDbContext();

   private IEntityARepository  aRepository;
   private IRepository<EntityB> bRepository;

   public IEntityARepository   ARepository 
   {
      get
      {
            if (this.aRepository == null)
               this.aRepository = new EFEntityARepository<EntityA>(context);

            return this.aRepository;
      }

   }

   public IRepository<EntityB> BRepository 
   {
      get
      {
            if (this.bRepository == null)
               this.bRepository = new EFRepository<EntityB>(context);

            return this.bRepository;
      }

   }

   //...more stuff
}

次のバインディングを追加します。

kernel.Bind(typeof(IEntityARepository)).To(typeof(EFEntityARepository));

しかし、これは正しくないと確信しています。または、少なくとも、それを行う適切な方法ではありません。

4

2 に答える 2

3

私があなたを正しく理解していれば、このようなジェネリック クラスの具体的に型指定されたバージョンから派生させることができます...

public class EFEntityARepository : EFRepository<EntityA>, IEntityARepository 
{
    //Add more opps
}

作業単位は次のようにする必要があると思います。

   public IEntityARepository   ARepository 
   {
      get
      {
            if (this.aRepository == null)
               this.aRepository = new EFEntityARepository(context);

            return this.aRepository;
      }

   }
于 2012-12-19T16:38:30.923 に答える
1

次のように元のコードを追加および/または変更することで、機能するようになりました。

//New interface for the extension of the repository.
//Is it possible to do this without defining this new interface? Doesn't seem like it.
public class IEntityARepository : IRepository<EntityA>
{
   void DoSomethingSpecificToEntityA();
}

//Add new class.
//It looks like you have to inherit from IEntityARepository as well.
public class EFEntityARepository : EFRepository<EntityA>, IEntityARepository
{

   public EFEntityARepository(MyDbContext context) : base(context) {}

   //add additional methods for EntityA
   public void DoSomethingSpecificToEntityA()
   {

   }

}


//Modify Unit of Work Interface as follows.
public interface IUnitOfWork: IDisposable
{
   IEntityARepository ARepository { get; }
   IRepository<EntityB> BRepository { get; }
   //...more stuff
}

//Modify Unit of Work Implementation as follows.
public class EFUnitOfWork: IUnitOfWork
{
   private MyDbContext context = new MyDbContext();

   private IEntityARepository aRepository;
   private IRepository<EntityB> bRepository;

   public IEntityARepository ARepository 
   {
      get
      {
            if (this.aRepository == null)
               this.aRepository = new EFEntityARepository(context);

            return this.aRepository;
      }

   }

   public IRepository<EntityB> BRepository 
   {
      get
      {
            if (this.bRepository == null)
               this.bRepository = new EFRepository<EntityB>(context);

            return this.bRepository;
      }

   }

   //...more stuff
}

それはうまくいきます...しかし、それは最善の方法ですか?

于 2012-12-19T17:44:52.697 に答える