5

私の現在のアプリケーション構造は次のとおりです。

  • モデルアセンブリ
  • データアセンブリ
    • ORMによって実装されるリポジトリインターフェイスを定義します
  • ORMアセンブリ
    • データアセンブリからリポジトリインターフェイスを実装します
    • Unity(IoCコンテナ)を使用して登録Data.IRepository<>しますORM.GenericRepository<>
  • 商談
    • データアセンブリとモデルアセンブリを参照します
    • Unityを使用してタイプを解決しますIRepository<>
  • UIアセンブリ
    • ビジネスアセンブリを参照します

この構造は、本質的にビジネス層をORMから切り離して実装していIRepository<T>ます。

この分離された構造の利点の1つは、ORMを比較的簡単に置き換えることができることです。たとえば、Entity FrameworkからNHibernateに移行したり、既存のORMをアップグレードしたりできます。私は現在、最初にEF 4.1コードを使用しており、NHibernate用に別のアセンブリを構築しています。

作業単位パターンの実装を検討しています。

このパターンはビジネスレイヤーで使用する必要があることを読みました(データアセンブリで定義されたインターフェイスを使用し、リポジトリパターンで行ったのと同じようにORMアセンブリに実装します)。現在、インスタンス化されたすべてのリポジトリには独自のDbContext /セッションがあり、その存続期間はリポジトリの存続期間に設定されています-これは悪いかもしれません-私の問題は、で動作する作業単位パターンを実装できるかどうかわからないことです異なるORM(むしろ、おそらくそうですが、私はスピードが上がらないだけです)。

これが頭に浮かぶ唯一のことです:

次の関数を持つデータアセンブリにIUnitOfWorkを作成します。object GetCurrentSession();次に、ORMアセンブリのリポジトリのコンストラクターに引数を設定し、適切なセッション/ DbContextにキャストします(NHibernateの場合はISession、Entity Frameworkの場合はDbContext)

誰かがこの状況について何らかの洞察を持っていれば幸いです。

4

2 に答える 2

0

私は解決策を見つけたかもしれません(まだ試していません):

データアセンブリの場合:

public interface IUnitOfWork : IDisposable
{
   void Start();
   T Current<T>();
   // IDisposable stuff
}

ORMアセンブリの場合:

public class GenericRepository<T> : IRepository<T>
    where T : PersistentEntity
{
    private ISession CurrentSession;

    public GenericRepository(IUnitOfWork uow)
    {
         CurrentSession = uow.Current<ISession>();
    }

    // other repository stuff here
}

public class NHhibernateUnitOfWork : IUnitOfWork
{
   private ISession CurrentSession;

   public void Start()
   {
      // instantiate CurrentSession
   }

   T Current<T>()
   {
      if(typeof(T) is ISession)
         return (T)CurrentSession;
      else
         return new NotImplementedException();
   }
}

// in the prism module
container.Resolve(typeof(IUnitOfWork), typeof(NHhibernateUnitOfWork));

ビジネスアセンブリでは:

IUnitOfWork uow = container.Resolve<IUnitOfWork>();
using(uow.Start())
{
    IRepository custRepo = container.Resolve<IRepository<Customer>>(uow);
    // do stuff here with cust repo
}

これは、IUnitOfWorkを具体的な実装から切り離すという概念の証明にすぎません。

于 2011-04-11T16:19:06.690 に答える
0

最近、作業単位とリポジトリパターンを使用して単純なASP.NET CoreCRUDAPIを実装する研究プロジェクトを作成しました。私のAPIコントローラーがIUnitOfWork抽象化によってのみ永続ストレージで動作するように作成しました。また、Dapper、Entity Framework Core、NHibernate用に別々のプロジェクトがあり、それぞれがIUnitOfWork特定のORM用に実装されています。

プロジェクトのリンクは次のとおりです:https ://github.com/pkirilin/UnitOfWorkExample

簡単な例を次に示します。

class SomeService
{
    private readonly IAppUnitOfWork _unitOfWork;

    // IAppUnitOfWork is inherited from base IUnitOfWork and added to DI container
    public SomeService(IAppUnitOfWork unitOfWork)
    {
        _unitOfWork = unitOfWork;
    }

    public async Task DoSomethingAsync(CancellationToken cancellationToken)
    {
        var entity = await _unitOfWork.WeatherForecasts.GetByIdAsync(..., cancellationToken);
        _unitOfWork.WeatherForecasts.Delete(entity);

        var newEntity = new WeatherForecast(...);
        _unitOfWork.WeatherForecasts.Add(newEntity);

        await _unitOfWork.SaveChangesAsync(cancellationToken);
    }
}
于 2022-01-01T14:33:23.857 に答える