Det dyker upp massor med frågor när jag ska ta fram ett nytt dokument som ska beskriva "framtida" arkitekturen i våra program. Dokumentet är till .NET utvecklare. Jag kör enligt denna(se länk nedan). Rätt likt det du beskriver fast med lite andra namn, stora skilnaden är att infrastruktur , db,mm, läggs längst ut i "arkitekturen". Använder du någon typ av facade lager? Man kan nog säga att jag får följande "fasader": Blir dessa olika lager sedan indelade i olika utvecklingsprojekt eller kodas allt i samma dll (för .NET utvecklare)? Jag brukar börja med Andreas kan du förklara för mig lite om onion arkitekture, för jag läste lite på det och verkar inte fatta hur det fungerar... :) Det funkar så här: "Detta interface implementeras sedan av en (eller flera) klasser i Infrastructure lagret. När man sedan kodar "Core"delen av applikationen så använder man sig endast av Interfacet. Den faktiska implementatonen låter man sedan en IoC-container "dependency injecta". Mao behöver "core" aldrig bekymmra sig om var interfacen implmenteras " Nja, eftersom att core bara jobbar med interfacen som ligger i "Domain Services" och inte med dom faktiska implementationerna så tycker jag nog inte att man kan säga att det blir ett beroende "utåt". Janne:Lagerindelning i .NET applikationer
1. Vilka lagerindelningar gör ni?
1.1 GUI - FACADE - BUSINESS – DATAACCESSOR - DATABASE
------------------------------VO------------------------------
Lagra data:
För att hantera objekt (t ex skapa och uppdatera) har GUI en referens till en FACADE som innehåller metoder för de olika operationerna. FACADE skickar sedan vidare VOObjektet till BUSINESS för kontroll och bearbetning som i sin tur skickar VOObjektet vidare till en DATAACCESSOR för lagring.
Hämta data:
1. t ex ett klickEvent
1.1 GUI frågar FACADE efter objekt.
1.2 FACADE frågar BUSINESS efter Object.
1.3 BUSINESS frågar DATAACCESSOR efter Objekt
1.4 DATABASEN returnerar DATA till DATAACCESSOR
1.5 DATAACCESSOR skapar VO och returnerar till BUSINESS
1.6 BUSINESS returnerar till FACADE
1.7 FACADE returnerar Objektet till GUI
Alla lagren har referenser till VO.
GUI har till FACADE och VO
BUSINESS har till VO och DATAACCESSOR
DATAACCESSOR har till VO och koppling till databasen
När man läser upp data returnerar DATAACCESSOR endast Dataset (.NET appl.) till BUSINESS som i sin tur skapar VOObjekt.
Tanken är som alltid att det ska vara så lite logik i GUI som möjligt. Kan man lyckas med detta behöver man inte göra så stora ingrepp i applikationen om den skulle behöva byta klient (Console, webb, Windows). Samma sak gäller för databasen (SQLServer, Oracle, DB2).
Hänger ni med på vad jag menar? om inte, gör ett inlägg så ska jag försöka förtydliga det.
Är detta overkill eller har ni några andra förslag?Sv: Lagerindelning i .NET applikationer
http://jeffreypalermo.com/blog/the-onion-architecture-part-1/
Funkar väldigt bra om man kör Domain Driven Design + TDDSv:Lagerindelning i .NET applikationer
I mitt fall vill jag påstå att facadelagret och dataaccessorlagret har ungefär samma funktion. De ska endast skicka vidare frågor och svar och frikopplar själva affärslogiken. På det sättet behöver man inte in och pilla onödigt mycket i kod som igentligen inte berörs. men frågan är om det är lite "Overkill"?Sv: Lagerindelning i .NET applikationer
"Domain Services" = fasad mot db, web-services + all annan infrastruktur
"Application Services" = omvärldens(WebGui,Fetklient,Batchar,WCF m.m.) fasad mot "min affärslogik"Sv:Lagerindelning i .NET applikationer
Sv: Lagerindelning i .NET applikationer
MyApp.Web (om det nu är en webapp)
MyApp.Core
MyApp.Infrastructure
Och sedan köra men namespaces under dessa. Man kan sedan bryta ut i fler projekt senare om man känner för det.Sv:Lagerindelning i .NET applikationer
Han säger att lagerna utanför känner till ett lager innanför (precis som vanligt, att lagert ovanför känner till lagret under...
Men sedan lägger han dataaccessen längst ut. Hur skall man kunna spara ner sin data då? Är det meningen att UI skall hantera det för det är ju det enda lager som har kontakt med infrastrukturen?!?!?
Det han berättar och visar i diagramen går ju inte ihop i verkligheten... jag måste ha missförstått något fundamentalt.
- MSv: Lagerindelning i .NET applikationer
I lagret som kallas Domain Service ligger det interface för dataaccess, i DDD använder man ofta det så kallade "Repository Pattern" (http://www.martinfowler.com/eaaCatalog/repository.html)
Detta interface implementeras sedan av en (eller flera) klasser i Infrastructure lagret. När man sedan kodar "Core"delen av applikationen så använder man sig endast av Interfacet. Den faktiska implementatonen låter man sedan en IoC-container "dependency injecta". Mao behöver "core" aldrig bekymmra sig om var interfacen implmenteras
Wow vad många svåra ord och koncept det blev :) (googla lite om du inte är insatt i allt)
Ett litet exempel:
Vi behöver kunna spara och ladda en Entitet som heter "Order". Då skapar vi ett repository-interface i domain services som heter IOrderRepository, på detta finns ex GetById(int id) och Save(Order order)
I vår "application layer" blir det då:
public class OrderService
{
private IOrderRepository orderRepository;
//vi dependecy injectar nu IOrderRepository
//den faktiska implementationen av IOrderRepository skickas sedan in av den IoC-container vi
//kör med, ex Windsor,MEF, Spring.net ,NInject Structuremap mfl
public OrderService(IOrderRepository orderRepository)
{
this.orderRepository = orderRepository;
}
public void CreateNewOrder(blablabla)
{
//vi skippar all validering transaktionern osv så det blir tydligare
//nu sparar vi i vårt "repository" -> som kan vara Xml-fil, DB, WS, InMemory , whatever (vi bryr oss inte)
orderRepository.Save(new Order{Bla="1",Blabla="2"});
}
}
Observera att det inte bara är repositories som ligger i Domain Services utan har ligger även Interface som är fasader mot all infrastruktur, andra system osv, ex IEmailService, IBillingSystem osv
Hoppas att det klarnade lite!Sv:Lagerindelning i .NET applikationer
Okej, då är jag med, men då "ljuger" han ju lite när han säger att de olika lagerna bara kan kalla inåt i cirklen, för core-delen kommer ju att kalla utåt även om det i koden inte finns någon stark koppling till dataaccess lagret. Den separeringen kan man ju lösa i vanlig top-down indelning också...
Same same but diffrent...
- MSv: Lagerindelning i .NET applikationer
Ett tydligt tecken på detta är att om du har alla olika lager i separata projekt så kommer du inte att ha någon referens till Infrastructure från nått av core-projekten -> mao så har core inget beroende till Infrastructure. Detta ger dig då full frihet att ändra implementationerna av all infrastruktur utan att det påverkar något annat lager. (så länge du implementerar samma interface givetvis)Sv: Lagerindelning i .NET applikationer
Tips, det finns ingen silver bullet.. olika projekt kan behöva olika typer av arkitektur..
Många kör fast i skiktade lösningar idag pga the old "Windows DNA" time.. Tänk på att COM+ skrevs ofta i VB6 och VB, man jobbade väldigt mkt med funktioner.
.Net öppnar upp dörren för Object Orientering med arv etc. OOP är perfekt för att återanvända kod, skapa mer "logiska" data strukturer etc. Mitt tips är att ta en titt på Domain Driven Design.
Mvh Fredrik Normén
ASP.Net MVP MEET ASPInsider
http://weblogs.asp.net/fredriknormen