Repositories - fråga kring implementationen

79 views
Skip to first unread message

Ai Bui

unread,
Sep 13, 2013, 5:20:41 AM9/13/13
to dddsv...@googlegroups.com
Hej,

Ganska färsk på DDD så jag behöver väl liten pointer kring det här.
Jag målar upp hur jag tror det bör vara och hoppas ni coola människor visar mig rätt.

Repository.
Har jag tänkt rätt om jag:

  • Skapar en implementation av ett repository som "tar" in ett domain object  (aggregate root)
  • I den implementationen, så mappar jag över state i mitt domain object till t.ex Entity framework data entiteter som skall användas för att persistera det mha EF.

Implementationen skulle då kunna se ut så här

   public class ProfileRepository : EFRepository<MYPROJ_DAL.Profiles>, IProfileRepository

    {

        public ProfileRepository(DbContext dataContext)

            : base(dataContext)

        {

        }



        public void RemoveProfiles(IEnumerable<Profile> profiles)

        {

            throw new NotImplementedException();

        }


        public void RemoveProfile(Profile profile)

        {

            throw new NotImplementedException();

        }


        public void AddProfiles(IEnumerable<Profile> profiles)

        {

            throw new NotImplementedException();

        }


        public void AddProfile(Profile profile)

        {

            //Convert to data entity. Maybe using automapper here?

            var profileEnt = new MYPROJ_DAL.Profiles();

            profileEnt.Presentation = profile.Presentation;




            //Insert data-entity, not the domain entity

            Insert(profileEnt);

        }


    }




Där dessa metoder deklareras i IProfileRepository, samt Insert-metoden finns implementerad i EFRepository som jobbar enbart mot EF-entiteter.
Tänker jag alltså rätt eller fel om det här med mappningen från domain objekt till persistence object? Samt är det så man bör göra?

Repositories har jag använt tidigare men då som ett abstraktionslager för att förenkla tester.

Mvh
Ai

Patrik Fredriksson

unread,
Sep 27, 2013, 4:36:41 PM9/27/13
to dddsv...@googlegroups.com
Hej!

Jag måste tyvärr börja med att erkänna att jag inte har superbra koll på Entity Framework. Precis som du skriver är det vanligen en aggregatrot som sparas och läses upp från en datakälla med motsvarande Repository. Så inte sällan finns det som du har här en Profile och ett tillhörande ProfileRepository.

Om jag skulle göra detta i t ex Java, som jag är mer bekant med, så skulle typiskt implementationen av Repository göra själva mappningen till datalagret direkt från domänobjektet/aggregatroten. Använder man en relationsdatabas och en ORM görs detta av ORM:en och det finns ingen anledning att kopiera över data till ett tillfälligt objekt på vägen. Använder man inget mapperramverk utan jobbar mot databasdrivern direkt så görs själva mappningen från domänobjekt till en SQL INSERT (eller motsvarande NoSQL statement) direkt i Repository-implementationen istället.

Men, det finns säkert någon som har mycket bättre koll på Entity Framework här som kan ett lite mer specifikt svar för EF.

Jag vet att Julie Lerman på senare tid intresserat sig för just kombinationen DDD och Entity Framework, en Google-sökning där någonstans borde kunna få några relevanta träffar. Julie kommer för övrigt till Øredev i höst med en presentation om just DDD och EF: http://oredev.org/2013/wed-fri-conference/entity-framework-in-core-business-applications-that-leverage-ddd

Hoppas detta var till någon liten hjälp.

/Patrik



2013/9/13 Ai Bui <ai....@vina.se>

--
Det här meddelandet skickas till dig eftersom du prenumererar på gruppen DDD Sverige i Google Groups.
Om du vill sluta prenumerera på den här gruppen och inte längre få någon e-post från den skickar du ett e-postmeddelande till dddsverige+...@googlegroups.com.
Om du vill göra ett inlägg i den här gruppen skickar du e-post till dddsv...@googlegroups.com.
Besök gruppen på http://groups.google.com/group/dddsverige.
Fler alternativ finns på https://groups.google.com/groups/opt_out.

Fredrik Klintebäck

unread,
Sep 27, 2013, 5:33:32 PM9/27/13
to dddsv...@googlegroups.com
Har inte kodat DDD med .Net och EF däremot med .Net och NHibernate.

Skulle titta på Entity Framework code first. Om jag förstått det rätt skulle implementationen av ditt repository bli så här:

public class ProfileContext: DbContext
{
   public DBSet<Profile> Profiles { get; set; }
}

public class ProfileRepository: IProfileRepository
{

    public void AddProfile(Profile profile)
    {
        using (var context = new ProfileContext())
        {
            context.Profiles.Add(profile);
            context.SaveChanges();
        }
    }
}

Torbjörn Kalin

unread,
Sep 27, 2013, 5:52:26 PM9/27/13
to dddsv...@googlegroups.com
Jag utvecklar Fredriks svar:

Man kan jobba med EF på två sätt. Antingen genererar du dina entiteter/domain objects utifrån en existerande databas eller så börjar du skriva entiteterna själv och skapar sedan en databas baserat på dessa.

Det första kallas för database first och är det du hittar flest exempel på. Microsoft har historiskt sett ofta haft kodexempel där man börjar med en Northwind-databas som man ska koppla ett UI på och denna variant är en fortsättning på detta. Koden som ligger mellan databas och UI anses som något nödvändigt ont som man helst vill undvika. Ofta ser man mycket logik i stored procedures som ett sätt att undvika C++/VB/C#-kod.

Det andra kallas för code first och är mer i linje med DDD. Att få till kod som mappar mot verksamheten/domänen är det primära. Databasen är en implementationsdetalj (något förenklat). Du handskriver dina entiteter och du handskriver dina mappningar mot databasen. Inga mellanobjekt (DTO:er) behövs.

Det du beskriver låter som database first och, som Fredrik nämner, titta gärna på code first istället.

(Ursäkta min något bittra framtoning, men jag är ganska trött på att stöta på system som är byggda efter första varianten)
/T

John Nilsson

unread,
Sep 28, 2013, 9:17:54 PM9/28/13
to dddsv...@googlegroups.com
Jag skulle nog tillägga att man bör ta en seriös funderare på att köra något simplare som Dapper eller ORMLite innan man hoppar på EF.

Just för DDD verkar ORMLite lite av en sweetspot (har inte testat dock), med den får en form av table per aggregate serialisering, lite som att jobba med en dokumentdatabas.

Har du redan en databas som du inte vill jobba om (typ table per concrete class eller så) så fundera på om inte SQL via Dapper fungerar precis lika bra som en code first mappning. Det blir betydligt mindre kod att hålla reda på.

Skall man ha någon nytta ur EF så bör man ha nytta av de features man får ur det. Identity mapping, dirty checking, mappning till Linq och så, och att denna nytta överväger komplexiteten i att felsöka skumma ORM-issues som att navigerings properties är null när man inte föväntar sig det, eller fundera över vilken SQL som genereras, eller att Linq2SQL är en läckande abstraktion där man måste hålla tungan rätt i munnen för att få equals, null checking och enkla string- och datumoperationer rätt.

Om du dessutom redan funderar på att mappa över din domän själv för skrivandet så kan du ju lika gärna fundera på om du inte skall ge dig på en immutable domänmodell ( http://blogs.msdn.com/b/dotnet/archive/2013/09/25/immutable-collections-ready-for-prime-time.aspx ) något jag misstänker inte blir så lätt om man försöker använda EF till att implementera modellen.
En immutable modell kan nog gå bra ihop med en framtida övergång till event sourcing om du väljer det spåret i framtiden.

Mvh,
John


2013/9/27 Torbjörn Kalin <torb...@kalin-urena.com>
Reply all
Reply to author
Forward
0 new messages