2010-12-17 16 views
9

Ich habe eine Methode in einem Repository mit einer sehr komplexen Geschäftslogik. Ich habe gerade gelesen, dass es in einem Repository keine Geschäftslogik geben sollte.Komplexe Geschäftslogik im Repository

Das Entfernen der Geschäftslogik von dieser Methode erfordert, dass ich die Logik auf zwei andere Repositorys verteile (weil es zwei andere Entitäten involviert).

Dann ist meine Frage-was für ein Muster sollte ich verwenden, um diese komplexe Logik zu implementieren? Es wird diese drei Repositories benötigen, aber ich kann es nicht in einen Controller legen, weil ich es wiederverwenden muss. Danke für Ihre Hilfe.

Antwort

9

Komplexe Geschäftslogik geht normalerweise in eine Service-Schicht. Ein Dienst kann von einem oder mehreren Repositorys abhängen, um CRUD-Vorgänge an Ihren Modellen durchzuführen. Somit kann eine einzelne Dienstoperation, die eine Geschäftsoperation repräsentiert, von mehreren einfachen Operationen abhängen. Dann könnten Sie diese Service-Schicht in Ihren Controllern und anderen Anwendungen wiederverwenden.

Offensichtlich sollte Ihr Dienst nicht von bestimmten Repository-Implementierungen abhängig sein. Um eine schwächere Kopplung zwischen der Service-Schicht und den Repositories zu ermöglichen, könnten Sie Schnittstellen verwenden. Hier ein Beispiel:

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 
    } 
} 

Jetzt alles, was übrig bleibt, ist Ihr DI Rahmen konfigurieren, dass diese spezifischen Dienst in Ihrem Controller zu injizieren.

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

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

Sie können sehen, wie Schnittstellen uns eine schwache Kopplung zwischen den Schichten ermöglichen. Die gesamte Installation wird vom DI-Framework durchgeführt und alles ist transparent und leicht testbar.

+0

Darin, in diesem Zusammenhang, was der beste Weg ist, verschiedene Repositories zugreifen von einem einzigen Dienst? Kannst du mir bitte auch mitteilen, welche Lösung ein IoC/DI wäre? – Chandu

+0

Vielen Dank Darin! –

+0

Danke für die Erklärung Darin – Chandu

1

Ich denke, Ihr Super-Repository brechen nur Single Responsibility-Prinzip. Ich würde Repository so einfach wie möglich (KISS-Muster;), und würde andere Schicht zwischen Controllern und Repository, e.q. erstellen Geschäftsschicht.

Zur Wiederverwendung und den Code zu vereinfachen haben einen Blick auf Dependency Injection (IoC implementieren)

Ich würde eigentlich vorschlagen, einen Blick auf SOLID Prinzipien haben.

2

Ich würde eine domänenorientierte Design-Ansatz verwenden. Ein sehr gutes Buch über DDD ist das folgende: .NET Domain-Driven Design with C#: Problem-Design-Solution. Suchen Sie auch nach Fowlers Enterprise Patterns und Evans Domain Driven Design Büchern. Die Grundidee ist, dass ein Repository grundsätzlich Infrastruktur ist. Die gesamte Domänenlogik wird in Ihr Modell übernommen.

Beispiel sieht eine Repository Methode wie folgt:

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

Auf der anderen Seite ein Modellobjekt wie folgt aussieht:

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

Vielen Dank das war wirklich aufschlussreich! –

Verwandte Themen