2010-12-17 11 views
9

非常に複雑なビジネスロジックを持つリポジトリにメソッドがあります。私はちょうどリポジトリにビジネスロジックがないはずであることを読んだ。リポジトリ内の複雑なビジネスロジック

この方法からビジネスロジックを削除するには、他の2つのリポジトリにロジックを配布する必要があります(他の2つのエンティティが関係するため)。

私の質問は、この複雑なロジックを実装するためにどのようなパターンを使用すべきですか?これらの3つのリポジトリを消費する必要がありますが、再利用する必要があるためコントローラに配置できません。ご協力ありがとうございました。

答えて

9

複雑なビジネスロジックは通常、サービスレイヤーに入ります。サービスは、モデルでCRUD操作を実行するために1つまたは複数のリポジトリに依存する場合があります。したがって、ビジネス操作を表す単一のサービス操作は、複数の単純な操作に依存することがあります。その後、コントローラや他のアプリケーションでこのサービス層を再利用することができます。

明らかに、あなたのサービスは特定のリポジトリの実装に依存すべきではありません。サービスレイヤーとリポジトリー間の弱い結合を実現するために、インターフェースを使用することができます。ここに例があります:

public interface IProductsRepository { } 
public interface IOrdersRepository { } 
... 

public interface ISomeService 
{ 
    void SomeBusinessOperation(); 
} 

public class SomeServiceImpl: ISomeService 
{ 
    private readonly IProductsRepository _productsRepository; 
    private readonly IOrdersRepository _ordersRepository; 

    public SomeServiceImpl(
     IProductsRepository productsRepository, 
     IOrdersRepository ordersRepository 
    ) 
    { 
     _productsRepository = productsRepository; 
     _ordersRepository = ordersRepository; 
    } 

    public void SomeBusinessOperation() 
    { 
     // TODO: use the repositories to implement the business operation 
    } 
} 

これで残っているのは、この特定のサービスをコントローラに注入するようにDIフレームワークを構成することです。

public class FooController : Controller 
{ 
    private readonly ISomeService _service; 
    public FooController(ISomeService service) 
    { 
     _service = service; 
    } 

    public ActionResult Index() 
    { 
     // TODO: Use the business operation here. 
    } 
} 

どのようにインターフェイスを使用すれば、レイヤ間の結合が弱いのかが分かります。すべての配管はDIフレームワークによって実行され、すべてが透過的で簡単にユニットテスト可能です。

+0

ダーリン、このような状況の中で、さまざまなリポジトリにアクセスするための最良の方法は何ですか単一のサービスから?また、IoC/DIを導入した解決策を教えてください。 – Chandu

+0

ありがとうダーリン! –

+0

説明をありがとうDarin – Chandu

1

あなたのスーパーリポジトリは単なる責任原則を破ると思います。 私はリポジトリをできるだけシンプルなものにして(KISSパターン;)、コントローラとリポジトリの間に他のレイヤーを作成します。ビジネス層。コードを再利用し、簡単にするために

は、依存性の注入を見て(IOCを実装)

実は私はSOLID原則を見てすることをお勧め。

2

私は、ドメイン駆動設計アプローチを使用します。 DDDに関する非常に良い本は次のとおりです:.NET Domain-Driven Design with C#: Problem-Design-Solution。 Fowlers Enterprise PatternsとEvans Domain Driven Designの書籍もご覧ください。基本的な考え方は、リポジトリは基本的にインフラストラクチャであるということです。すべてのドメインロジックがモデルに入ります。モデルオブジェクトは、次のようになります一方

public void InsertAddresse(Company company) 
{ 
    foreach (Address address in company.Addresses) 
    { 
     this.InsertAddress(address, company.Key, (company.HeadquartersAddress == address)); 
    } 
} 

例リポジトリメソッドは次のようになります

public class Contact : Person, IAggregateRoot, IHasAddresses 
{ 
    private string jobTitle; 
    private string email; 
    private string phoneNumber; 
    private string mobilePhoneNumber; 
    private string faxNumber; 
    private string remarks; 
    private Company currentCompany; 
    private IList<Address> addresses; 

    public Contact() 
     : this(null) 
    { 
    } 

    public Contact(object key) 
     : this(key, null, null) 
    { 
    } 

    public Contact(object key, string firstName, string lastName) 
     : base(key, firstName, lastName) 
    { 
     this.jobTitle = string.Empty; 
     this.email = string.Empty; 
     this.phoneNumber = string.Empty; 
     this.mobilePhoneNumber = string.Empty; 
     this.faxNumber = string.Empty; 
     this.remarks = string.Empty; 
     this.currentCompany = null; 
     this.addresses = new List<Address>(); 
    } 

    public string JobTitle 
    { 
     get { return this.jobTitle; } 
     set { this.jobTitle = value; } 
    } 

    public string Email 
    { 
     get { return this.email; } 
     set { this.email = value; } 
    } 

    public string PhoneNumber 
    { 
     get { return this.phoneNumber; } 
     set { this.phoneNumber = value; } 
    } 

    public string MobilePhoneNumber 
    { 
     get { return this.mobilePhoneNumber; } 
     set { this.mobilePhoneNumber = value; } 
    } 

    public string FaxNumber 
    { 
     get { return this.faxNumber; } 
     set { this.faxNumber = value; } 
    } 

    public string Remarks 
    { 
     get { return this.remarks; } 
     set { this.remarks = value; } 
    } 

    public Company CurrentCompany 
    { 
     get { return this.currentCompany; } 
     set { this.currentCompany = value; } 
    } 

    public IList<Address> Addresses 
    { 
     get { return this.addresses; } 
    } 

    protected override void Validate() 
    { 
     //some logic here 
    } 

    protected override BrokenRuleMessages GetBrokenRuleMessages() 
    { 
     return new ContactRuleMessages(); 
    } 
} 
+0

本当に洞察力のあるありがとうございます! –