Jag funderar på en sak som jag inte har hittat någon bra lösning på (tycker jag iallafall) och det är applikationservicerna i DDD.
Säg att jag har 2 entiteter. User och Order. Och så från mitt UI så vill jag kunna spara ner och hämta dessa från databasen, i vanliga fall så kallar jag direkt till repositoryt för att göra detta, men nu så har jag en cache som jag skall hämta ifrån om det finns värden och om de inte finns så skall jag hämta från databasen, lika så när jag spara så skall det sparas både till cachen och till databasen...
Då kommer min applikationservices med i bilden (nej jag tycker inte mitt repository skall känna till cachen av olika anledningar). Och frågan är helt enkelt vad skall applikationservicerna ha för namn och därmed vilken funktionallitet som skall ligga i dem.
Jag har testat att både ha "SaveEntityApplicationServices"/"LoadEntityApplicationServices" där man både kan hämta och spara alla entiteter och även "UserApplicationServices" där man kan hämta och spara User Entity och "OrderApplicationServices" där man kan hämta och spara Order.
Mest korrekt tycker jag det blir med "SaveUserApplicationServices"/"LoadUserApplicationServices"... men det blir så grymt många klasser att skriva så man kräks...
Jag brukar jämföra med Session (NHibernate) som är ganska generisk.
Så du kan väl egentligen ha något liknande
T applicationSession.Load<T>(id); // hämtar från cachen om inte finns i cachen hämtar från db
void applicationSession.Refresh(entity); // Laddar om entiteten från databasen
void applicationSession.SaveOrUpdate(entity); // sparar ner till cache och db
Om du implemmenterar cachen själv, så behövs ju egentligen bara en dictionary i bakgrunden som med IDictionary<object, object>
Jag skulle tagit bort ordet application från applicationService. Om du ändå vill trycka på att de är applicationsservicar så lägg de i en mapp som eller projekt som heter ApplicationServices.
Vad är syftet med att särskilja dessa två i olika service:r?SaveEntityApplicationServices och LoadEntityApplicationServices? Jag skulle nog haft dessa i en och samma service för att ge utvecklaren ett samlat API men det beror givetvis på hur stora dessa servicar blir. Men jag tror inte du har problem med storleken på servicen i detta fallet.
...jag tycker inte mitt repository skall känna till cachen av olika anledningar...
Nej, jag tycker inte heller att den implementationen av repository-interfacet som hanterar själva persisteringen dessutom ska implementera en cache.
Däremot tycker jag att man kan skapa en annan in-memory-implementation av repository-interfacet, vars uppgift alltså är att implementera en cache dvs använda objekt som lagras i minnet istället för att varje gång hämta dem mha ett nytt databasanrop. När de inte redan finns i minnet (eller när en ny version ska lagras) så delegerar implementationen vidare till den riktiga implementationen som hanterar själva persisteringen till/från databasen.
Klientkoden kan således hela tiden anropa de vanliga metoderna som är definierade på ett repository-interface vars implementationsklass kan betraktas som en virtual proxy.
Däremot tycker jag att man kan skapa en annan in-memory-implementation av repository-interfacet, vars uppgift alltså är att implementera en cache dvs använda objekt som lagras i minnet istället för att varje gång hämta dem mha ett nytt databasanrop. När de inte redan finns i minnet (eller när en ny version ska lagras) så delegerar implementationen vidare till den riktiga implementationen som hanterar själva persisteringen till/från databasen.
Ahhaaa... smidigt, då är det ju dessutom asenkelt att bara tabort cachen om jag inte vill ha den. Varför tänkte jag inte på det.... ibland blir man lite hemmablind... tack så mycket.
Jag tycker fortfarande en generisk hanterare som hanterar cache och sql, om man nu handknackar allt själv så kan man fortfarande få det att bli ganska generiskt annars är det exakt detta som NHibernate gör.
Jag tycker fortfarande en generisk hanterare som hanterar cache och sql, om man nu handknackar allt själv så kan man fortfarande få det att bli ganska generiskt annars är det exakt detta som NHibernate gör.
Kan inte använda mig av NHibernate, då anropen från mitt repository görs via WCF-services. Dessutom så kan jag hämta 2 olika typer av objekt, för att minska datamängden. Om jag hämtar en hel lista som skall visas så hämtas bara en delmängd av datan för det objektet, och när man sedan ber om att få se mer detaljer av ett objekt så kontrolleras i cachen om det fulla objektet finns där, om det inte finns så hämtas det via WCF-Servicen och läggs in i cachen så man slipper hämta det igen om man vill se datan.
Jag har dessutom en synk som skickar ut objekt som blir uppdaterade av andra klienter, så att den datan som finns i cachen alltid skall vara så färsk som möjligt.
Jag tycker fortfarande en generisk hanterare som hanterar cache och sql, om man nu handknackar allt själv så kan man fortfarande få det att bli ganska generiskt annars är det exakt detta som NHibernate gör.
Kan inte använda mig av NHibernate, då anropen från mitt repository görs via WCF-services. Dessutom så kan jag hämta 2 olika typer av objekt, för att minska datamängden. Om jag hämtar en hel lista som skall visas så hämtas bara en delmängd av datan för det objektet, och när man sedan ber om att få se mer detaljer av ett objekt så kontrolleras i cachen om det fulla objektet finns där, om det inte finns så hämtas det via WCF-Servicen och läggs in i cachen så man slipper hämta det igen om man vill se datan.
Jag har dessutom en synk som skickar ut objekt som blir uppdaterade av andra klienter, så att den datan som finns i cachen alltid skall vara så färsk som möjligt.
- M
Japp då förstår jag :)
259 ms totalt · 4 externa anrop · v20260731065814-full.86ec41c2