0

私は MVC3 アプリケーション開発の初心者です。現在、要件として次のアプリケーション技術が必要です。

  1. MVC3 フレームワーク
  2. IOC フレームワーク – オブジェクト作成を動的に管理する Autofac
  3. Moq – 単体テスト
  4. エンティティ フレームワーク
  5. Model クラスのリポジトリと Unit Of Work パターン

上記の点に関する基本的な考え方を探るために多くの記事を読みましたが、それでも「リポジトリと作業単位のパターン」について少し混乱しています。基本的に私が理解している作業単位は、すべてのリポジトリ オブジェクト間で単一の DB コンテキストを共有するためにリポジトリ パターンに従って実行されるパターンです。したがって、ここに私の設計があります。

IUnitOfWork.cs

public interface IUnitOfWork : IDisposable
{
    IPermitRepository Permit_Repository{ get; }
    IRebateRepository Rebate_Repository { get; }
    IBuildingTypeRepository BuildingType_Repository { get; }
    IEEProjectRepository EEProject_Repository { get; }
    IRebateLookupRepository RebateLookup_Repository { get; }
    IEEProjectTypeRepository EEProjectType_Repository { get; }
    void Save();

}

UnitOfWork.cs

public class UnitOfWork : IUnitOfWork
{
    #region Private Members

    private readonly CEEPMSEntities context = new CEEPMSEntities();
    private IPermitRepository permit_Repository;
    private IRebateRepository rebate_Repository;
    private IBuildingTypeRepository buildingType_Repository;
    private IEEProjectRepository eeProject_Repository;
    private IRebateLookupRepository rebateLookup_Repository;
    private IEEProjectTypeRepository eeProjectType_Repository;

    #endregion

    #region IUnitOfWork Implemenation

    public IPermitRepository Permit_Repository
    {
        get
        {
            if (this.permit_Repository == null)
            {
                this.permit_Repository = new PermitRepository(context);
            }
            return permit_Repository;
        }
    }

    public IRebateRepository Rebate_Repository
    {
        get 
        {
            if (this.rebate_Repository == null)
            {
                this.rebate_Repository = new RebateRepository(context);
            }
            return rebate_Repository;
        }
    }

}

PermitRepository .cs

public class PermitRepository : IPermitRepository
{
  #region Private Members

  private CEEPMSEntities objectContext = null;
  private IObjectSet<Permit> objectSet = null;

  #endregion

  #region Constructors

  public PermitRepository()
  {
  }

  public PermitRepository(CEEPMSEntities _objectContext)
  {
      this.objectContext = _objectContext;
      this.objectSet = objectContext.CreateObjectSet<Permit>();
  }

  #endregion

  public IEnumerable<RebateViewModel> GetRebatesByPermitId(int _permitId)
  {
     // need to implment
  }

}

PermitController .cs

public class PermitController : Controller
{
    #region Private Members       
    IUnitOfWork CEEPMSContext = null;
    #endregion

    #region Constructors

    public PermitController(IUnitOfWork _CEEPMSContext)
    {
        if (_CEEPMSContext == null)
        {
            throw new ArgumentNullException("Object can not be null");
        }
        CEEPMSContext = _CEEPMSContext;
    }

    #endregion
}

ここで、「TestRepository.cs」などの新しいリポジトリを生成する方法を考えています。同じパターンを使用して、次のような複数のリポジトリ オブジェクトを作成できます。

RebateRepository rebateRepo = new RebateRepository ()
AddressRepository addressRepo  = new AddressRepository()

なぜなら、作成したいRepositoryオブジェクトが何であれ、最初にPermitControllerクラスに実装されているUnitOfWorkのオブジェクトが必要だからです。したがって、個々の Repository クラスで同じことを行うと、Unit Of Work の原則が再び破られ、オブジェクト コンテキストの複数のインスタンスが作成されます。

したがって、どんなアイデアや提案も高く評価されます。

ありがとうございました

4

1 に答える 1

1

インターフェイスIUnitOfWorkの責任が多すぎます。新しいリポジトリを追加するたびに、IUnitOfWorkインターフェースとそのすべての実装を変更する必要があります。

代わりに、このようなものはどうですか?

public interface IUnitOfWork
{
    int SaveChanges();
}

次に、このインターフェイスを Entity Framework ObjectContext または DbContext に実装できます。

public MyCustomContext : DbContext, IUnitOfWork
{
    // ... this class already implements the SaveChanges method
}

次に、コンストラクターで作業単位を各リポジトリに挿入できます。AutoFac は、同じ HttpContext 内で使用される複数のリポジトリ間で同じインスタンスが共有されていることを確認できます。

public class PermitRepository : IPermitRepository
{
    #region Private Members

    private readonly IObjectSet<Permit> _objectSet;
    private readonly IUnitOfWork _unitOfWork;

    #endregion

    #region Constructors

    public PermitRepository(IUnitOfWork unitOfWork, IObjectSet<Permit> objectSet)
    {
          _unitOfWork = unitOfWork;
          _objectSet = objectSet;
    }

    #endregion

    public IEnumerable<RebateViewModel> GetRebatesByPermitId(int _permitId)
    {
       // need to implment
    }
}

次に、コンストラクターでリポジトリーをコントローラーに注入すると、IUnitOfWork は自動的にリポジトリーに注入されたコンストラクターになります。

public class PermitController : Controller
{
    #region Private Members       
    private readonly IPermitRepository _permitRepos;
    #endregion

    #region Constructors

    public PermitController(IPermitRepository permitRepos)
    {
        if (permitRepos== null)
        {
            throw new ArgumentNullException("permitRepos");
        }
        _permitRepos = permitRepos;
    }

    #endregion
}

リポジトリからデータをクエリする場合、実際には何の作業も行っていないため、ここでは IUnitOfWork インターフェイスは適用されないことに注意してください。エンティティを選択するときではなく、エンティティを挿入、更新、および削除するときに適用されます。

于 2012-06-04T16:37:13.543 に答える