Gladh skrev:
Fredrik nu pratar vi nog olika användningsområde för interfacen. IList exempel är ju inte till för att MS skall snabbt kunna byta ut sin List-klass mot en annan klass. Utan mer för att beskriva beteende för klasser.
När vi prata interfacen till IRepository så använder vi interfacen för att vi enkelt skall kunna byta ut vårt MySQL-Repository mot ett SQL-Repository eller WS-Repository. Och om du då först skapar ditt MySQL-Repository i ditt domänlager och så får du betydligt svårare att "byta ut det", visst du kan ju alltid skriva ditt nya SQL-Repository i ditt domänlager också.. :).
Om du lägger ditt MySql-Repository som ett eget assembly så kan du enklare byta ut det mot ett Sql-Repository om du använder dig av IRepository. Men om du lägger IRepository interfacet i MySql-Repositoryt så måste ju ditt Sql-Repository ha en referens till MySql-repository och det är inte speciellt bra.
Dessutom var lägger du dina "fake" repository? Ligger de också i domänlagret, eller ligger de i en eget assembly? För de om något är inget som man vill ha med i produktionsmiljön, bättre att få ett slag direkt över fingrarna om man "glömt" att peka om så man inte använder sina fakerespository, än att råka upptäcka att det bara är test data som man kör på i produktion....
- M
Om IList, andra använder den för sina egna implementationer av listor.
Till 95% så kommer du inte behöva byta ut dina Repo, gör du det så kan du enkelt ändra dom du redan har, eller använda dig av Visitor Pattern. Eller tex använda ADO.Net EF, som kan gå mot olika datakällor, eller ditt egna alternativ. Det jag försöker säga är att det spelar ingen roll om "orginal" Repos ligger i den assembly där dess interface ligger, eller separat, går lika lätt att byta ut. Alla Repos vi skapar kommer att ändå behöva ha en ref till våra entiteter, sedan kör vi med Factories som "gömmer" Repositories faktiska existens.
När det kommer till Stubbar ("Fake" Repo) Repos, så lägger jag dom till mitt TestPorjekt för jag tycker dom hör hemma där. En snabb bild på hur jag brukar skapa mina projekt:
Nsquared2.<SubSystem>.DomainLayer
Entities
Repositories
<CustomerRepsitory>
Interfaces
<ICustomerRepository>
Nsquared2.<SubSystem>.TestProject
Stubs
StubCustomerRepository
Samla mycket med försiktighet i en assembly och kör med namspace för att minska på assemblies. OBS! Tidigare separerade jag Repos till en egen Assembly, men efter att jag har jobbat i projekt med massor av class libs i en solution, så gick jag över till mindre assemblies och mer namespace istället, för att slippa massor av dependency referencer. Nu kör jag med denna modellen även för små projekt, mer av vana och att jag trivs med den.
Skulle min Infra förändras i Repos, så är det stor sannolikhet att hela min app kommer alltid köra med den nya. Då kan jag lika gärna uppdatera mina Repos jag har, går snabbare än att skriva nya. Skulle det vara så att jag vill ha kvar mina orginal Repos, så skapar jag en ny assembly som refererar till Nsquared2.DomainLayer.dll vilket den måste för att komma åt entiteterna. Min Repos-factory tar hand skapandet av rätt Repo, tex:
var customerRepository = RepositoryFactory.Create<ICustomerRepository>();
Sedan i tex XML står det:
<object id="ICustomerRepository" type="Nsquared2.<SubSystem>.Repositories.CustomerRepository, Nsquared2.<SubSystem>.DomainLayer.dll"/>
Där det går att konfigurera vilken instans min ICustomerRepository är mappad mot.
Men återigen, det är en smak sak, det finns inget rätt eller fel med det du gör eller det jag gör. Mitt är ett arv från stora apps och jag föredrar så få assemblies som möjligt, för jag gillar inte att ha massa dependency ref och .dller som ska deployas, utan så få som möjligt, och sedan pga det Patrick Smacchia säger om assemblys vs namespace. Jag tror inte vi kommer någon vart längre.. Du har hittat en modell som du tycker funkar bra för dig, jag har hittat ett en funkar bra för mig, det är huvudsaken. Men självklart är diskutionen intresant varför olika väljer att göra på olika sätt.