3

リポジトリ パターンを実装しましたが、かなりうまく機能します。

public interface IServiceRepository
{
    User GetUser(int id);
    User GetUser(string email);
    User GetUser(string email, byte[] password);
    //SkipCode
}

//Service repository where I keep extended methods for database manipulation
public class ServiceRepository : IServiceRepository
{
    private readonly IRepository<User> _userRepository;
    private readonly IRepository<Order> _orderRepository;
    private readonly IUnitOfWork _unitOfWork;

    public ServiceRepository(IRepository<User> userRepository, IRepository<Order> orderRepository, IUnitOfWork unitOfWork)
    {
    }

    //SkipImplementation        
}

IServiceRepositoryコントローラーからいくつかのメソッドにアクセスしたいときは、これを行います

public class AccountController : Controller
{
    private readonly IRepository<OrderDetail> _orderDetailRepository;
    private readonly IRepository<UserDetail> _userDetailRepository;
    private readonly IServiceRepository _serviceRepository;

    public AccountController(IRepository<OrderDetail> orderDetailRepository, IRepository<UserDetail> userDetailRepository, IServiceRepository serviceRepository)
    {
        _orderDetailRepository = orderDetailRepository;
        _userDetailRepository = userDetailRepository;
        _serviceRepository = serviceRepository;
    }
}

ご覧のとおり、このシナリオでは注入IRepositoriesします。必要に応じて、または必要に応じてIServiceRepository注射することもあります。IRepositoriesIServiceRepository

質問は、すべてIRepositoriesをに移動する必要があるかもしれませんIServiceRepository。そして、すべてのコントローラーで埋め込みのみIServiceRepositoryとからアクセスIRepositoriesIServiceRepositoryますか? IServiceRepositoryこの実装は、コントローラーにのみ挿入されるため、より明確に見えます。ただし、たとえばRepositorie<User>から1 つにアクセスするには、ServiceRepository他のすべてのリポジトリをビルドして挿入する必要があるためServiceRepository、アプリケーション全体の速度が低下する可能性があります。どう思いますか?

4

2 に答える 2

3

私の答えは物議を醸しているので、我慢してください:)

現時点では
、リポジトリの構築と注入にほとんど時間がかからないはずです。私はあなたのリポジトリが作成されたときに接続を開かないと仮定しているので、マイクロ最適化について気にせず、ただそれを機能させてください:)

結果のインターフェースが小さく(たとえば、10個程度のメソッド以下)、焦点が絞られ、明確な目的がある限り、インターフェースをマージできます。


サイドコメント
リポジトリパターンの必要性は何ですか?データベースを簡単に切り替えることを(または最も近い将来の計画で)許可しますか?ほとんどの場合、リポジトリは大規模なやり過ぎであり、メンテナンスの問題です。

このコードを検討してください

public interface IServiceRepository
{
    User GetUser(int id);
    User GetUser(string email);
    User GetUser(string email, byte[] password);
    //SkipCode
}

それは私に何を教えてくれますか?さて、一般的な名前から、このインターフェースが何をするのか理解できませんでした。それは、サービスのサービス、抽象化よりも抽象化のようなものです。しかし、メソッド定義から、それはsで何かをすることがわかりますUser

なぜ明示的に使用するのIUnitOfWorkですか?使用しているデータプロバイダーによってまだ実装されていませんか?

このすべてのアーキテクチャの代わりに(もちろん可能であれば)、ORMを直接使用するだけで、これは実行と保守が簡単で、信頼性が高く、高速です。

于 2012-07-19T11:34:08.927 に答える
1

ServiceRepository は、独自のリポジトリよりもサービス レイヤーのドメイン サービスに近いようです。

ドメイン サービスは通常、さまざまなデータ リポジトリとの一連のやり取りを調整します。たとえば、顧客リポジトリから顧客をロードし、注文リポジトリから注文リストをロードして、顧客とそのすべての注文の統一されたビューを表示します。このようなドメイン サービスは、アプリケーションの周囲に運用上の境界を作成するために使用され、データ アクセスのさまざまなシーケンスを抽象化します。

これは素晴らしいアプローチですが、あなたが抱えている問題は、あなたがそれを十分に行っていないことだと思います. アプリケーションの操作を一連のドメイン サービスにカプセル化する必要があると判断した場合、コントローラがリポジトリにアクセスする必要はありません。一方、コントローラーがそのリポジトリーを取得し、リポジトリー自体にアクセスすることを決定した場合、ServiceRepository クラスとそれに類する他のクラスは、基本的にユーティリティ・クラスになります。

2 つのオプションがあるようです。サービス レイヤーを改善して、コントローラーがリポジトリを必要としなくなるようにします。

public class AccountController
{
    public AccountController(IAccountsService service)
    {
        _service = service;
    }

    public void SomeActionMethod(Foo someParams)
    {
        _service.SomeAction(someParams);
    }
}

または、ServiceRepository を呼び出します。これは、一定のデータ アクセス シーケンスを実行するためのショートカット ユーティリティです...

public class AccountController
{
    public AccountController(ICustomerRepository customerRepo, IOrderRepository orderRep)
    {
        _customerRepo = customerRepo;
        _orderRepo = orderRepo;
    }

    public void SomeActionMethod(Foo someParams)
    {
        var utility = new CustomerOrderBuilderUtility(_customerRepo, _orderRepo);

        var customerWithOrders = utility.GetCustomerAndOrders(someParams.CustomerId);

        // some domain logic...
    }
}
于 2012-07-19T11:37:36.540 に答える