What is Good Practice in .NET System Architecture Design Concerning Multiple Models and Aggregates
I am developing a larger enterprise architecture and I am in doubt on how to separate the models and design them. There are several points that I would like to suggest for: - models to define - a way to define models
Currently my idea is to define:
- Kernel (domain) model
- Repositories retrieve data for this domain model from a database or other store.
- A business logic model that will contain business logic, validation logic, and more specific form options, data retrieval methods
- View models prepared for specially formed data output, which will be analyzed by different kinds of views (web, silverlight, etc.).
For the first model, I am puzzled about what to use and how to define the mode. Should these model objects contain collections and in what form? IList, IEnumerable or IQueryable? - I am thinking of immutable collections that IEnumerable is, but I would like to avoid huge collections of data and offer access to the business logic tier using LINQ expressions so that query trees are executed at the data tier and only retrieve the data really needed for situations like the one when I retrieve a very specific subset of items among thousands or hundreds of thousands.
What if I have an item with several thousand bids? I can't just create an IEnumerable collection for the model and then get the list of items in some repository method or even a business model method. Does it have to be IQueryable so that I can actually push my queries to the repository entirely from the business logic model layer? Should I just avoid collections in my domain model? Should I only invalidate certain collections?
Should I separate or integrate the domain model and BusinessLogic?
The data will be processed through repositories that will use the domain model classes. Should you use repositories directly, using only classes from the domain model like data containers?
This is an example of what I had in mind: Architecture Drawing <http://img199.imageshack.us/img199/7364/arch1p.jpg
So my Domain objects will look like (eg.)
public class Item
{
public string ItemName { get; set; }
public int Price { get; set; }
public bool Available { get; set; }
private IList<Bid> _bids;
public IQueryable<Bid> Bids
{
get { return _bids.AsQueryable(); }
private set { _bids = value; }
}
public AddNewBid(Bid newBid)
{
_bids.Add(new Bid {....
}
}
Where Bid will be defined as a regular class.
Repositories will be defined as data lookup factories and used to retrieve data in another (business logic) model, which will again be used to retrieve data in ViewModels, which will then be displayed by different consumers.
I would define IQueryable interfaces for all aggregate collections to gain flexibility and minify data retrieved from a real data store.
Or should I make the domain model "anemic" with pure data warehouse objects and all collections are defined for the business logic model?
One of the most important questions: where can IQueryable collections be assembled? - All the way from Repositories to Business model or not at all and expose only solid IList and IEnumerable from Repositories and handle more specific queries within the business model, but have finer methods for fetching data in repositories.
So what do you think? Do you have suggestions?
a source to share
I don't think forcing this kind of design in every application in the enterprise is a good idea in the first place. This is very specific. How can you predict what the needs of individual applications will be?
Secondly, what you presented is not really a domain oriented design. It's similar to Microsoft's blissful n-tier approach. You have data structures in all three layers. Why decouple your "domain model" from your business model? A rich domain model containing both data and behavior should be sufficient for most complex systems. A view model can be built on top of this model (simple, classic solution) or directly from the database (CQRSish solution). The latter seems to work better in complex scenarios.
You ask, the item has thousands of rates. Well, maybe the stake is an aggregate root (missing domain concept) and shouldn't be contained in any collection.
My advice: if you want a domain model, stick to DDD modeling techniques (Eric Evans, Jimmy Nilsson) and don't literally follow the App Archi guide. Add some CQRS to your solution as needed to clean up the UI issues from the model. This way you avoid all sorts of collection handling problems.
a source to share