Repository Model: cum să Lazy Load? sau, dacă am împărțit acest Agregat?

voturi
66

Am un model de domeniu care are conceptul de un editor și un proiect.

Un Editor deține un număr de proiecte, și un proiect are nu numai un proprietar Editor, dar, de asemenea, un număr de membri Editor. Prin urmare, un editor are, de asemenea, o serie de proiecte „unite“.

Sunt o abordare DDD pentru modelarea acest lucru și folosind modelul Repository pentru persistenta. Cu toate acestea, eu nu Grok modelul suficient de bine încă pentru a determina cum ar trebui să fac acest lucru.

Sunt de lucru pe presupunerea că Editor și de proiect sunt potențial în același agregat, cu radacina fiind Editor. Prin urmare, pot obține un Editor și apoi enumera proiectele sale, și ar putea de acolo enumere editori membre ale proiectelor.

Cu toate acestea, dacă sunt permise doar pentru a prelua editori din depozitul meu, nu face acest lucru înseamnă că trebuie să se încarce toate proiectele din magazia atunci când am obține editorul pe care le deține? Și dacă vreau să sarcină leneș Editors membru, proiectul are nevoie de o referință la magazia precum?

În mod alternativ, dacă am împărțit agregatul și au un depozit Editor și un depozit de proiect, cum ar trebui să se ocupe de o tranzacție de peste două, cum ar fi atunci când se adaugă un nou proiect la un editor? De exemplu:

Editor e = new Editor(Editor Name);
editorRepository.Add(e);

Project p = e.CreateProject(Project Name);
projectRepository.Add(p);    // These two lines
editorRepository.Save(e);    // should be atomic

Sunt misinterpreting intenția de model Repository?

Întrebat 19/01/2009 la 15:10
de către utilizator
În alte limbi...                            


4 răspunsuri

voturi
3

Aceasta depinde de necesitățile aplicației. Dacă este o mare problemă pentru a încărca toate proiectele pentru un anumit Editor, apoi încercați un model de încărcare leneș ca un proxy virtual .

În ceea ce privește încărcarea alene Editors membre ale unui proiect, dacă utilizați Virtual Proxy, eu nu văd o problemă injectarea proxy cu EditorRepository, deoarece nu considerăm proxy pentru a face parte din domeniul.

Dacă împărțim Agregat, puteți investiga unitatea de lucru model ca o soluție la Atomicitate. Această problemă, însă, nu este unic pentru DDD și eu sunt sigur că există și alte soluții pentru comportament tranzacțional.

Publicat 23/01/2009 la 01:45
sursa de către utilizator

voturi
4

Cum despre divizarea responsabilităților într-un EditorOwner și un EditorMember?

Fără a cunoaște domeniul, mi-ar imagina că ar avea responsabilități diferite - de exemplu, EditorOwner ar putea fi destul de bogat (și ar putea fi rădăcina totală), dar proiectul ar putea avea nevoie să știe doar o cantitate limitată despre membrii săi, așa obiectul EditorMember poate fi destul de ușor.

Aceste obiecte de domeniu pot, de asemenea, se referă la utilizatori, dar care ar fi într-un alt context.

Asta ajuta lucrurile, sau pur și simplu face mai complicat?

Publicat 23/01/2009 la 03:55
sursa de către utilizator

voturi
0

Aici aveți 2 relații diferite, una pentru proprietate și unul pentru calitatea de membru.

Relația proprietate este unul simplu pentru mulți (un singur proprietar pentru fiecare proiect). Relația de membru este de multe la multe (multe editori prin proiect, in mai multe proiecte de către editor).

Ai putea oferi o proprietate proprietar pe clasa de proiect, și să ofere o metodă pe ProjectRepository pentru a obține toate proiectele deținute de un anumit Editor.

Pentru mai multe relație, oferă o proprietate asupra membrilor clasei de proiect, precum și o metodă pe ProjectRepository pentru a obține toate proiectele care conțin specificat Editor ca membru.

Se pare că, de asemenea, editori și proiecte sunt entități, probabil, aș împărți agregat, dar, probabil, acești termeni au un înțeles specific în contextul tău care fac subentities unui agregat.

Publicat 11/02/2009 la 12:01
sursa de către utilizator

voturi
30

Sunt misinterpreting intenția de model Repository?

Am de gând să spun „da“, dar știu că eu și fiecare persoană cu care am lucrat a cerut același lucru pentru același motiv ... „Tu nu te gândești 4 - dimensional, Marty“.

Să-l un pic simplifica și stick cu constructori în loc de Creare metode mai întâi:

Editor e = new Editor("Editor Name");
e = editorRepository.Add(e);

Project p = new Project("Project Name", e);
p = projectRepository.Add(p);

Dedesubt, depozitul dvs. de proiect este stocarea întotdeauna un proprietar valid ( p.EditorId) în datele proiectului așa cum este creat, și cu toate acestea te re-popula proiectele unui editor, acesta va fi acolo. Acesta este motivul pentru care este o bună practică pentru a pune toate proprietățile cerute în constructori. Dacă nu doriți să treacă întregul obiect, doar e.Idva face.

Și dacă vreau să sarcină leneș Editors membru, proiectul are nevoie de o referință la magazia precum?

Acum, cu privire la modul de a re-popula proiectele redactorului la cerere, aveți câteva opțiuni, în funcție de ceea ce merge pentru. Drept Repository spune că doriți:

IEnumerable<Project> list = projectRepository.GetAllProjects()
                                .Where(x => x.editorId == e.Id);

Dar de unde să-l puneți? Nu in proiect, sau Editor, ai dreptate, sau vor trebui să aibă acces la arhive și că nu e bine. Fragmentul de mai sus este slab cuplat, dar nu este reutilizabil pe cont propriu. Tocmai ai atins limitele Repository de model.

Următorul este un strat adaptor pentru aplicația dvs., cu o sursă partajată de arhive ( StaticServiceWrapper) și fie un fel de EditorAdapter obiect (sau Agregat sau orice ai le numim) sau acum puteți amesteca în metodele de extensie , care poate vorbi cu orice și toate registrele necesare fluent. Nu l - am făcut exact în acest fel într - un sistem de producție, ci pentru a vă arăta un exemplu concis:

public static class Aggregators
{
    // one to one, easy
    public static Editor GetOwner(this Project p)
    {
        return StaticServiceWrapper.editorRep.GetEditorById(p.editorId);
    }

    // one to many, medium
    public static IEnumerable<Project> GetProjects(this Editor e) 
    { 
        return StaticServiceWrapper.projectRep.GetAllProjects()
                .Where(x => x.editorId == e.Id);
    }

    // many to many, harder
    public static IEnumerable<Editor> GetMembers(this Project p)
    {
        var list = StaticServiceWrapper.projectMemberMap.GetAllMemberMaps()
                        .Where(x => x.projectId == p.projectId);

        foreach ( var item in list )
            yield return StaticServiceWrapper.editorRep.GetEditorById(item.editorId);
    }
}

Practic, o dată dvs. GetAll, GetById, Add, Actualizare, Eliminare depozit de obiecte se face, ai să lase asociațiile în pace și să sus ierarhia obiectelor / strat la părțile distractive , cum ar fi adaptoare și cache - uri și logica de afaceri ( „Oh , mea!“ ).

Publicat 14/05/2009 la 03:40
sursa de către utilizator

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more