6

リポジトリ パターンを実装する ASP.NET MVC アプリケーションでは、特定のリポジトリの一般的な焦点にまだ関連している場合、データに関連しないメソッドをリポジトリに配置することが適切かどうかに興味があります。たとえば、ProductImages を追加および削除するためのメソッドを持つ ProductsRepository があるとします。これらの ProductImages は、データベースとローカル ファイル ストアにも部分的に表現されています。ProductImage を削除する必要がある場合は、リポジトリ メソッドを使用してデータベースから行を削除する必要があります。また、そのイメージに関連付けられているファイルをストレージ メディアから削除する必要もあります。IO 操作はリポジトリに属していますか、それともより適切な場所がありますか?

先ほど説明したような状況で私が行っていることの 1 つは、リポジトリに静的メソッドを提供することです。これにより、データベースに保存されているファイル名と事前定義されたディレクトリ パターンを使用して、特定の ProductImage へのパスが提供され、プログラムで生成されます。 . これはリポジトリの使用目的外ですか?


編集

そのような操作がリポジトリに属していない場合、そのような操作は MVC パターンのどこに配置する必要がありますか? 必要に応じてリポジトリを呼び出し、コントローラから静的に呼び出すことができる、コントローラとリポジトリの間に別のレイヤーを配置することは理にかなっているように思えます。

4

3 に答える 3

4

リポジトリパターンに関するより大きな懸念は、単一責任の原則に違反しているという事実だと思います。クラスには、データベース内のデータの操作など、1つの責任が必要です。別のクラスでファイルIOを処理する必要があり、関数を1層上のクラスにグループ化できます。

クラスが変更される理由は1つだけであり、ファイルIOおよびdb呼び出しを処理するリポジトリクラスには2つあります。ファイルシステムレイアウトの変更、またはデータベースの変更。

編集

編集の質問に対処するために、MVCシナリオでこれを実装する方法を次に示します(これは、生活を楽にするために何らかの依存性注入を使用していることも前提としています)。

// Controller class
public class ProductsController
{
    private IProductService _productService;

    public ProductsController(IProductService productService)
    {
        _productService = productService
    }

    public void RemoveImage(int productId, int imageId)
    {
        _productService.RemoveImage(productId, imageId)
    }
}

public class ProductService: IProductService
{
    private IProductRepository _productRepository;
    private IProductImageManager _imageManager;

    public ProductService(IProductRepository productRepository, IProductImageManager imageManager)
    {
      _productRepository = productRepository;
      _imageManager = imageManager;
    }

    public void RemoveImage(int productId, int imageId)
    {
        // assume some details about locating the image are in the data store
        var details = _productRepository.GetProductImageDetails(productId, imageId);
        // TODO: error handling, when not found?
        _imageManager.DeleteImage(details.location);
        _productRepository.DeleteImage(productId, imageId)
    }
}

次に、特定のニーズに合わせた具体的な実装で意味のあるインターフェイスに基づいて、IProductImageManagerとIProductRepositoryを実装します。

于 2009-08-19T15:41:03.367 に答える
2

私は最近、新しいリポジトリを設計し、これと同じ質問に苦労しました。リポジトリに追加のメソッドを含めることになりました。

しかし今振り返ると、より良い解決策は、リポジトリをより集中させ、リポジトリと緊密に統合されたサービスに追加のメソッドを配置することだったと思います。

上記の例では、ProductsServiceに「DeleteProductImage」メソッドを設定して、ProductsRepository.DeleteImageを呼び出し、ストレージメディアからの画像の削除を処理することができます。

これにより、リポジトリがクリーンに保たれ、「DeleteImage」ロジックのみに焦点が当てられますが、リポジトリを呼び出して画像を削除すると同時に、ストレージメディアとのやり取りも処理する、呼び出す必要のある単一のメソッド( "DeleteProductImage")が提供されます。リポジトリに直接関連していない、画像が削除されたときに発生する可能性のあるその他のこと。

于 2009-08-19T15:43:16.047 に答える
1

リポジトリは、アプリケーションが消費するデータがどこにどのように保存されるかという懸念からアプリケーションを分離するためにあります。その上で、リポジトリは、このコンテキストでデータベースとファイルベースのアクティビティの両方を処理するのに絶対に適切な場所です。

于 2009-08-19T15:41:07.440 に答える