views:

55

answers:

1

Hi, I am trying to get myself accustomed with TDD, DI and Pattern-based Development. I am by far not new to Application Development, but since I plan to start a (big) new Project in a few months I want to be prepared and do it right from the start ;).

The current architecture is based on a WCF-based AppServer, a MS SQL Database and WPF/WCF Clients who access the AppServer.

I have 3 Entities, Stay, Apartment and Guest. Stay has a Reference to 1 Apartment and 1 Guest. Each of the 3 Entities has its own Repository (since they are, as far as I understand it, Root Entities). The Entity-Classes are POCO's and are being used in the Server aswell as in the Client. The Repositories use an OR/Mapper internally (at the moment Entity Framework).

Currently there are 3 WCF-Services, one for each Entity that handles CRUD-Operations...more will follow in time.

Now to my problem... In which Layer should the referencing of the Entities take place? The Repositories should not depend on each other (for easy replacement, but should that be needed than they could depent on each other loosely coupled since I already use LightCore as DI-Container). As far as I understand it the references could either be set in the Repositories or in the Services.

What would be the "correct" or more elegant way?

Maybe I misunderstood something but the referencing doesn't seem to be really performant. For example, if I have 10,000 Stays, 15,000 Guests and 150 Apartments. If I want to return 500 Stays including the linked Guest from the Service (500 seems reasonable although I would like to return more) then that would be up to 500 * 15,000 = 7.5 Million Iterations. That doesn't seem to be very performant. Sure, one could cache that but caching only helps to a certain point.

Or did I am under a misconception somewhere in my design? Every advice would be appreciated :)

[Edit] I'm still unsure on how to proceed with my design so any help would be greatly appreciated.

A: 

In my opinion, the trick with the repository pattern is to think of not only in the context of atomic root entities, but also having a parallel context for aggregation. To illustrate, say I have just two entities, Book and Author. I will have a repository for each but to say the two operate exclusively on Book or Author would be untrue (especially while using EF). A book may have multiple authors and and authors may have published multiple books.

For instance, to create a new book I'd use a create operation on the book repository but to associate a new book with an existing author (say for some reason this scenario exists), I might have a method on my author repository called AddBookToAuthor(int authorId, Book book). This would effectively retrieve the author in question, add the book to the author's Books collection and if this book is a new Book, actually create the new book instance in the data store.

James Alexander
So you're saying that the referencing should take place inside the repository? While I AM using EF at the moment, I want to reserve the option to change the datasource for a single repository w/o the need to change other repositories that access the first repo (like with the way u described).
Pharao2k
Assuming you're using straight POCO's and passing just POCO's in and out of the repository, you technically speaking could have one repository using EF, one using NHibernate, and one using straight up ADO.NET. At the end of the day, the Repository would be your Business Layer's boundary for doing data access.
James Alexander
Okay to clarify, in my aforementioned scenario, would the GetAllStays() Method of the Stay-Repository access the Guest- and Apartment-Repository and return the List of Stays with the Guests and Apartments already referenced?
Pharao2k
No, in the scenario I'm describing it would not. The Stay-Repository should be able to get a list of Stay instances with it's Guest and Apartment properties instantiated and associated if that is your desire. In EF this is particularly easy to do even with POCO's with something like the following: db.Stays.Include("Guest").Include("Apartment").Where(s => s.StayId = stayId)With the exception of some very specific edge cases, I've never been a fan of having one repository reference another repository.
James Alexander
Okay now I'm confused :D With the prerequisite that every repository handles it's own aggregate root and each repository is easily replaceable w/o influencing the others where should the referencing take place? Executes GetAllStays() the GetSomethingById() of the other repositories to fill the references and return the stays with references filled or does it return the Stays with the references == null so that the calling class (the WCF Service for example) has to ask the other repositories for the related entities and fill the references itself?
Pharao2k
It would be really appreciated if someone could answer that ^^ In your EF-Example the Repositories would not be exchangeable since with "db.Stays.Include("Guest").Include("Apartment").Where(s => s.StayId = stayId)" the Stay-Repository would access the databases behind the Apartment- and Guest-Repository directly, so if I exchange the Apartment-Repo with another Repo (which retrieves the Apartments via WCF or whatever) the Stay-Repo would still access the (not being used anymore or maybe not even existing anymore) the Apartment Database-Table.
Pharao2k