If domain entities aren't anemic, so they embed specific-usage behavior inside themselfes, is there a need/point to use/build specific domain services? How about validation should it go inside an entity?
What way is more flexible for unit testing?
Thanks!
Typically when an anemic model is not being used, you'll still have needs that require domain specific services. That's because the non-anemic models (or just, models, if you will) should contain code that allows themselves to be manipulated, but should refrain from taking dependencies on other models, especially models that are not directly related through a parent/child relationship.
Separate domain services will allow you to maintain that separation and still provide rich functionality, since they domain services can potentially be aware of a larger view of the entire domain model.
As for validation, it is not uncommon for these models to provide their own validation, just remember that sometimes the valid state of a model depends on a larger context that the model may not be aware of, so external validation is probably still going to exist.
Lastly, unit-testing flexibility is going to depend quite a bit on your application, and the underlying technology (such as language choice). I haven't seen many cases where either approach has enough influence on unit testing by itself.
Domain Services are necessary when you have a Domain Model because there is functionality that's not a part of your entities.
Think for example about a Repository or a Factory. The interface for a Repository will probably be in your Domain Layer but the implementation in your Infrastructure Layer. With a Factory, both the implementation and interface will be in your Domain Layer.
These Domain Services are used from your Application Layer. The goal of an application layer is to make sure that everything is in place so the Domain Model can do his work. This could mean loading specific entities from Repositories and then calling domain specific functions on them.
Validation should go inside an Entity. For example, lets suppose you have a Money class.
public class Money
{
public Money(string currency, int amount)
{
Currency = currency;
Amount = amount;
}
public int Amount { get; set; }
public string Currency { get; set; }
}
If the Money class is not allowed to have a negative amount, where would you validate this?
The best place to do this is inside the class. An entity is responsible for its own state.
In a Money class, this is easy to see but for example with an Order class with OrderLines the Order is responsible for checking if there are duplicate OrderLine items that should be merged (saves shipping costs!)
Domain Services usually contain domain functionality that doesn't naturally fit into one of your entities. It's often functionality that is required by many other domain objects, potentially making the domain service a big nexus where many objects connect.
As for validation, it can be in various places depending on when and what you want to validate :
Factories enforce invariants upon creation of an entity
Aggregate roots enforce invariants that concern the whole aggregate
Basic validation is also often performed inside the entities themselves
You can have custom validation that requires data related to the current state of the application, in which case the validation is more likely to be done in the Application layer.
Related
In DDD, many models are there:
Domain model, which is used in busiess or application layer.
Data access model, which is used in data access or data repository layer.
Data transfer model (DTO), which is used in presentation layer.
Beacuse of them, the disadvantages raiseļ¼
They violate the DRY principle, beacuse many duplicate fields exist between them and can't avoid.
They need a lot of irritable mapping to conversion between different layers.
How can we reduce the irritable Models?
Ultimately, it is about choosing your battles. One of the main considerations in a Domain-Driven solution is that it is focused on isolating and encapsulation of the domain. That means that, by that very premise, you are not going to want to use it as an approach in every single project. You need to have an inherent complexity that you are trying to reduce, and you do so by modeling the needs of the business and the needs of the application independently. This means that you are not creating a single system, but one or more systems (your application or applications) that are utilizing a consummate subsystem (your domain).
Personally, I do not have the three types of data-bearing classes that you describe in any of my projects. Instead, I have only my domain model and a view model representation based on each distinct UI requirement. I have found that the need to have a separate set of persistence classes to be superfluous. There are several ways to eliminate the need for persistence classes, such as POCOs with code-first EF, object databases/NoSQL, and separation of your read model and write model. I opt for a combination of the last two, personally, in most cases.
The translation layer between the domain and application/UI is something that I find to be required, because the "truth" that the domain represents is infallible. But, in order to attain a usable interface into the domain, the application will sometimes have additional or differing requirements to the domain. That means that this translation layer is not just about field mapping, it is about encapsulation of differing concepts and isolation of usage scenarios.
Since the domain should have absolutely no knowledge of how it is used, that means that there is a requirement for translation and it is not something that should be attempted to be worked out of the system. I have seen people who have used their domain classes directly in the UI, as the actual model, and that is more heinous (in my opinion) than having to create a translation layer. You are looking at it from the perspective of just being for translation, but remember that it is also about isolation. Introduction of new concepts, changing of existing concepts, and other changes within the domain can effectively be intercepted in translation to prevent impact in the UI, and vice versa.
That sounds trivial, but in an enterprise setting, it is not uncommon for there to not be just a single application that utilizes the domain, but multiple applications. Consider the possibility that your domain is serving a desktop application, a web application, and a REST API. Each of those will have their own specific application requirements that are separate from your business requirements. They also will likely want to represent the domain differently from each other. This means that each of them will likely have things such as different validation requirements, different views into your domain, and unique application functionality. Regardless of all of this, the domain remains happily oblivious to it all. You will have to translate differently for each, somewhere above the domain.
If you are finding that your models are looking exactly like your domain, with a majority of it being one-to-one mappings, you might want to take a step back and look for some other issues that might be occurring. I find a large number of two-way mappings of singular fields to be a code smell. Not always, but often, this is an early sign of an anemic domain model. I personally go as far as to enforce architectural requirements on my domain model, such as requiring that properties be read-only (forcing them to be set through a constructor for existing data and changed through methods on the classes), etc. It is fairly trivial to write architectural unit tests which will reflect your domain classes to inspect them for possible violations of such rules. But, the point is if you find translation to be your pain point, make sure that your domain model is not just acting as a data container. Anemic domain models are an extraordinarily common pitfall in DDD implementations, and with an anemic domain model, there is actually very little benefit to a DDD approach at all, as you are taking the power and responsibility away from the place it should be enforced.
Business requirements should be reflective of the needs of the domain, which is not the same thing as the usage patterns of the domain. Ideally, you should be telling the domain how you want to change its state, and the domain should be applying the domain logic to allow or disallow those changes. If you find yourself pulling down a full domain model representation for a part of the domain, translating the entire thing to a model or DTO, modifying that model or DTO, translating it back to the domain representation, and sending the whole thing back in, you likely have a larger problem.
You may want to review your understanding of DRY. A good starting point is DRY is about Knowledge -- Matthias Verraes (2014).
You may also want to look at Gary Bernhardt's 2012 talk Boundaries.
The key idea is this - the DTO model is an API contract between the domain model and the presentation components. It gives us the freedom to aggressively update/adapt/improve the domain model without breaking the existing presentation component.
Similarly, the data access model is an API contract between the domain and the presentation component. Not only does this mean that the interface between the domain and persistence is stable, but it also provides a stable contract between the current implementation of the domain model (which writes data today) and future implementations of the domain model (which read back that same data tomorrow).
1. This is not about Domain-Driven Design
Separating models comes with your ancestral n-layer architectural style. It dates back long before DDD was around.
2. You don't have to have that many models
If your application is simple enough, you can ditch some of them.
"Data access model" comes to mind first. It's only a recent addition to the DDD paraphernalia. But you can do without just as well, with a minor impact on your domain model.
And guess what, you may even find out that you don't need a rich domain model at all... Some applications are just better off as CRUD.
If you find something "irritable", get rid of it and see for yourself what the benefits/drawbacks are. Code police won't come knocking at your workplace and lock you up for favoring simplicity over so-called orthodoxy.
No, there are not many models. There are multiple representations of the same model. This distinction is very important.
In the domain model, the entity is responsible of making sure that it's state is instact. For instance, the ApprovedAt property may not be set unless ApprovedBy is set at the same time. This is usually done by adding behavior to the entity. I do it by always setting all property setters to private and then add methods every time the entity need to change state.
The DTO is responsible of transferring state between over application boundaries. But when you do DDD correctly you do not want to transfer the domain entity to the client. You want it to remain safe within the server. Thus the role of the DTO is much more important. You might even have multiple DTOs for the same entity. For instance, I might have a UserListDTO which contains a subset for just listing entities and maybe a UserDetailsDTO which is designed for the user details page. For writes you just transfer the mutated state or send command influenced DTOs (ApproveUserDTO).
Finally it's important that the domain entity isn't forced to be designed in a certain way just to be able to persist it. That's why we have the data entity. It will be design so that everything can be persisted in a efficient way. The user might have a data entity called User and one called UserField depending on the domain entity design.
The conclusion is that if you models look exactly the same you are doing something wrong (from the perspective of DDD).
I am trying to learn some concepts about DDD and the part of persisting Aggregates is confusing me a bit. I have read various answers on the topic on SO but none of them seem to answer my question.
Let's say I have an Aggregate root of Product. Now I do not want to inject the ProductRepository that will persist this aggregate root in the constructor of the Product class itself. Imagine me writting code like
var prod = new Product(Factory.CreateProductRepository(), name, costprice);
in the UI layer. If I do not want to inject my repository via dependency injection in the Aggregate Root, then the question is where should this code go? Should I create a class only for persisting this AR? Can anyone suggest what is the correct & recommended approach to solve this issue?
My concern is not which ORM to use or how to make this AR ORM friendly or easy to persist, my question is around the right use of repositories or any persistence class.
Application Services
You are right, the domain layer should know nothing about persistence. So injecting the repository into Product is indeed a bad idea.
The DDD concept you are looking for is called Application Service. An application service is not part of the domain layer, but lives in the service layer (sometimes called application layer). Application services represent a use case (as opposed to a domain concept) and have the following responsibilities:
Perform input validation
Enforce access control
Perform transaction control
The last point means that an application service will query a repository for an aggregate of a specific type (e.g. by ID), modify it by using one of its methods, and then pass it back to the repository for updating the DB.
Repository Ganularity
Concerning your second question
Should I create a class only for persisting this AR?
Yes, creating one repository per aggregate is a common approach. Often, standard repository operations like getById(), update(), delete(), etc. are extracted into a reusable class (either a base class or by aggregation).
You can also create additional repositories for non-domain information, e.g. statistical data. In these cases, make sure that you don't accidentally miss a domain concept, however.
I am having trouble connecting the dots from many posts I have read (and coming to realize I probably need to buy Eric Evans book instead of relying on loads of internet material) I am trying to adhere to domain driven design, but I am having trouble on the best method to communication from the presentation layer to my domain before saving my data back to the database. To keep it simple, right now I have a user class that can have a list of jobs. When a user opens the application their active directory information is queried and this class is populated with their data as long as they have the app open. Then, the user can edit an existing job if they own it or create a new one. I started creating a service class that uses my UnitOfWork class thinking this would act as my communication, but that is where I am stuck.
Current Setup:
DAL - EF 6 generated POCOs and DbContext, Repository, Unit of Work
Domain - Entities, Repository & Unit of Work interface, domain interface services I refer to in this post?
Presentation - MVC (intranet), concrete service?
Questions:
Is the service class the best class to implement for this type of communication (and for creating new instances of my domain classes (e.g. a method to create a new job)? I realize I could use a factory pattern, but I did not want to get too complicated yet)? Would the service reside in the domain layer or do I create a separate project for an application layer? Then would the interface go in the domain layer and the concrete implementation go into the application layer? I feel like that could be over complicating the app. Also, is the service WCF or can I just create my own classes?
How do I map the ViewModel in my MVC layer back to the domain using this service (if that is the best way) without the presentation layer leaking in to the service? I've read up on DTOs, but then is that overkill in the service layer? Or is it okay to expose my domain entities as the ViewModel? I must be thinking about this incorrectly. I cannot picture how this interaction would look in a controller without some leakage. Sorry for all the questions, and thanks.
public class User
{
public int Id{ get; set; }
public string WindowsId{ get; private set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string FullName { get { return FirstName + " " + LastName; } }
public string Email { get; set; }
public string WorkPhone { get; set; }
public List<Job> Jobs { get; private set; }
public void AddJob(Job job)
{
if(job == null)
throw new Exception("Job is null");
var newJob = new Job(this) //tell the job that this user is creating the job
{
Description = job.Description,
DueDate = job.DueDate,
Name = job.Name,
Reason = job.Reason
};
Jobs.Add(newJob);
}
}
UPDATE: My Solution
I ended up taking a little bit from everybody's answers.
#granadaCoder - I used my EF POCOs as the classes to pass around as DTOs because most of the time that is the data I was displaying to the user in my ViewModel. So it allowed me to use the DTOs as the ViewModels
#ChrisPratt - you are correct. Doing this prevented a lot of extra work. All I did was create a service that had all the queries I needed. And if I ever had to change the EF it would still not bother my other layers. All I would have to do is create the repository and UOW
#MilivojMilani - I did have repeating logic in the controller so the service layer kept me aligned with the DRY principal
#Yorro - I used your points and references to reinforce the design since I was still unsure about the service layer setup. Since this is a smaller project, I setup another folder with my service and interface that I created, no WCF
Stay away from the Repository/Unit of Work pattern if you're using Entity Framework. EF is itself an implementation of this pattern. If you want to abstract Entity Framework, then implement a service pattern that returns fully-baked data exactly how you need it. It's best illustrated with an example:
With EF/Repository
IQueryable<Post> posts = db.Posts.Where(m => m.BlogId == blog.Id && m.Status == PostStatuses.Published && m.PublishDate <= DateTime.Now).OrderBy(m => m.PublishDate);
With Service
List<Post> posts = service.GetPublishedPostsForBlog(blog);
The two key differences here are:
You're returning data already pulled from the database with the service; a repository/EF will return a queryable that may or may not have been executed against the database yet.
All your logic goes into the service method with a service. Whereas, with a repository/EF you build your query in place.
That said, don't get so hung up on the layers of your application. It's not about how many layers you have and what you call them, but rather about abstracting logic away from pieces of your application that shouldn't need to know how to construct that logic. A controller action to return a list of published blog posts, for example, shouldn't need to know what qualifies a post as being "published". That's domain logic that should go somewhere else (like the service method that returns this dataset). The idea is simply to follow the single-responsibility principle: a class/method/etc. should do one thing and do it well. Your controller action should only concern itself with returning the view (and doing the bare minimal amount of work to fetch what that view needs).
As far as mapping goes, the term explains exactly what you do, so I'm not sure of the confusion here. If you want to map Post to PostViewModel for example:
var model = new PostViewModel
{
Title = post.Title,
Content = post.Content,
...
}
Or with a list of objects, you can employ LINQ:
var model = posts.Select(m => new PostViewModel
{
Title = m.Title,
Content = m.Content,
...
}
If you question is simply: how do I do this easier? Then, you can look into a third-party mapping library like AutoMapper.
The Service Layer
The service layer serves as the application's boundery, it encapsulates your domain entities, in other words, it protects your domain. All communication to the domain must go through the service layer. But the Domain Model (at its purest form) should not have any reference to the Service Layer or any other infrastructure layers (DAL/Presentation).
http://martinfowler.com/eaaCatalog/serviceLayer.html
Would the service reside in the domain layer or do I create a separate project for an application layer? Then would the interface go in the domain layer and the concrete implementation go into the application layer?
If you are already segregating your layers into their own projects, then the service layer should have its own project.
Is the service WCF or can I just create my own classes?
The simplest service is just a class, see an example of a service layer straight from Microsoft Tutorials:
http://www.asp.net/mvc/tutorials/older-versions/models-(data)/validating-with-a-service-layer-cs
Here is another example on how to refactor an MVC using a service layer
http://www.arrangeactassert.com/asp-net-mvc-controller-best-practices-%E2%80%93-skinny-controllers/
How do I map the ViewModel in my MVC layer back to the domain using this service (if that is the best way) without the presentation layer leaking in to the service? I've read up on DTOs, but then is that overkill in the service layer? Or is it okay to expose my domain entities as the ViewModel? I must be thinking about this incorrectly. I cannot picture how this interaction would look in a controller without some leakage.
This question is another topic altogether. DTO is a good way for the service layer to communicate with outside layers.
Your questions are very good, and in fact it is the most frequently asked.
Is it overkill to use DTO in the Service Layer?
Is it okay to expose the guts(domain) of my application to outside layers?
How would the service layer interact with outside layers without leakages?
Where should the DTO reside?
I've answered the same questions here: https://stackoverflow.com/a/21569720/1027250
This image provides overhead view on how a service layer fits into a multi-layer architecture. Note that this is not absolute or perfect for every project, you should approach a pattern depending on the need of the project. Additional layers adds complexity, it is a long term investment on a long term project with a large team.
1.If you're using MVC you may or may not have a service layer. Ask yourself a following question - do you use this functionality on more than one place? If the answer is yes - use the application service (not domain service). If no, put it in the MVC controller itself.
Don't put any hydration logic in the domain layer. Domain layer in DDD shouldn't know anything about persistence. Controller/Application service should fetch the data using repository interfaces and save the data using same interfaces. In your case, you should be fetching and saving only the User class, while Job should be below it as aggregate root child. Using UnitOfWork and Repository is perfectly fine. Here is a good article on it =>
http://www.asp.net/mvc/tutorials/getting-started-with-ef-5-using-mvc-4/implementing-the-repository-and-unit-of-work-patterns-in-an-asp-net-mvc-application
2.It is perfectly normal to, in some cases, use domain object as ViewModel class. In other more complex cases, you will have to map properties manually. Mapping is usually best done as extension method on ViewModel class. Some use AutoMapper though I'm against using it when mapping presentation classes to domain. All this mapping work should NOT be done in domain layer. You might have a lot of viewmodel classes and it would bloat the domain layer with presentation layer logic.
Hope it helped.
Bit per bit, I am undestanding and becoming more proficient with ASP.NET MVC4. However I'm still failing to be clear in my mind concerning this very important point. Let us say that I have a model :
public class WorkPaper
{
public int WorkPaperID { get; set; }
public string name { get; set; }
public string description {get ; set; }
public bool verified {get; set;}
public DateTime dateAdded {get; set;}
}
I use this model with Entity Framework code first approach and I have the following DB Context :
public class NicodemeContext : DbContext
{
public DbSet<WorkPaper> Workpapers { get; set; }
}
What I don't understand is : what is the Model Layer and what is the Data Access Layer. To me the WorkPaper class tends to be part of the DAL since I designed it and choosed my properties names and types (navigations property etc...) to fit the EF pattern. But the problem is that if i'm right, I really don't see where I should put the business logic.
In that specific case, if I want to add a rule saying that a Workpaper cannot be sent if it hasn't been verified and an other rule saying that if it's been added more than 2 weeks ago it can't be submitted (strange rules but that's just an example). Where should I add them ? Do I have to create an other class, but then where should I put it and what should it contain ? Isn't it going to be very redundant with the class I already have ? But in the other hand, since that class is "database oriented", wouldn't it be messy to add business rules there ?
My point is really in understanding where I have to put my business logic and to understand the difference between the DAL and the model. I have difficulties to identify the DAL and the Model Layer since their look very similar to me. I would like to do things the correct way.
(Basically, I don't know where to code "my program" with MVC ! I'm not comfortable as soon as I want to code the functionality I'm actually interested in. I feel like i'm not doing the things right)
There is no single "right" way to do this. There are probably a number of "wrong" ways, but as with most things much of it is "it depends".
You will find a lot of opinions on this. And much of that depends on how you are approaching it. For instance, #Tarzan suggests using your model for both business logic and data layer entities. Others, suggest creating separate Entity objects, business objects, and view model objects.
If you're making a relatively simple, CRUD type application then you can probably do as #Tarzan suggests and have few problems. However, in more complex applications you start to run into problems doing it this way. For instance, what happens when your business logic is different from your data logic? If you combine them into a single set of entities, then you are forced to make the logic the same everywhere, or spend a lot of time retrofitting.
The most flexible approach is to keep your Presentation, Business, and Data layers completely separate. In this way, the requirements of (for example) the UI don't need to match the other layers. (Here's a simple example, imagine that for some kinds of objects, a particular field is allowed to be null, but not for others. Your data layer would only know that the field is nullable, while your business layer would know that certain objects can't be null).
However, that approach can have a lot of overhead, and require what seems like duplicate code in each layer... creating a lot of extra effort, which is often times not worth it for small or simple applications.
One key thing to remember is that MVC is a Presentation pattern. That means it ONLY concerns itself with the user interface. The "model" is typically considered to be a "view model", which is the model the view uses. This model is customized for the views requirements. For instance, by using Data Attributes that you would not put on a data model.
If you consider MVC to be strictly presentational, then MVC doesn't care what kind of data access you're using, nor does it care what kind of business layer you're using. It could be a service layer, or a repository, or a business objects library (such as CSLA).
A common pattern in MVC applications is to use a service layer of some type, or a repository if you're simply doing CRUD operations. There is typically some kind of mapping system between each layer, using technologies like AutoMapper or custom build mapping classes.
The point here is simply this. MVC doesn't concern itself with business and data, so don't get yourself all worked up over how these fit into an MVC application. They don't, or at least they don't other than with very basic interfacing.
Your application is a collection of objects, in what can be considered an architecture. This architecture is made up of different layers. MVC, Service, Data, etc.. MVC may be the primary user interface, but that doesn't mean everything else is also MVC.
You can put the NicodemeContext class in the DAL and the WorkPaper class in the Model Layer.
The Model Layer is where you define your business domain. This is where your business logic goes.
The Data Access Layer is where you read and write to the database and populate the objects from your Model Layer.
A useful technique is to use partial classes in the Model. In one partial class keep everything that might be written by a code generator and everything handwritten in the other partial class. For example, if you use a tool to generate a partial WorkPaper class it will usually contain all of the properties and associations. In the handwritten partial class you can place your business logic. If something changes with your domain, this allows you to run the class generator again and again without fear of losing your business logic. I know that you said you are using code-first but still, partial classes can be useful.
Models are where you put business logic, and communicate with the Data Access Layer which saves & retrieves data. Your views are for presenting the user interface. The controllers are for passing information between views and models. It takes awhile to get the feel of MVC, but you are asking the right questions and are on the right track.
Hope this helps. Cheers.
Something on my mind about structuring a system at a high level.
Let's say you have a system with the following layers:
UI
Service Layer
Domain Model
Data Access
The service layer is used to populate a graph of objects in the domain model. In an attempt to avoid coupling, the domain model will be not be persistence aware and will not have any dependencies on any data access layer.
However, using this approach how would one object in the domain model be able to call other objects without being able to load them with persistence, thus coupling everything together - which I'd be trying to avoid.
e.g. an Order Object would need to check an Inventory object and would obviously need to tell the Inventory object to load in some way, or populate it somehow.
Any thoughts?
You could inject any dependencies from the service layer, including populated object graphs.
I would also add that a repository can be a dependency - if you have declared an interface for the repository, you can code to it without adding any coupling.
One way of doing this is to have a mapping layer between the Data Layer and the domain model.
Have a look at the mapping, repository and facade patterns.
The basic idea is that on one side you have data access objects and on the other you have domain objects.
To decouple you have to: "Program to an 'interface', not an 'implementation'." (Gang of Four 1995:18)
Here are some links on the subject:
Gamma interview on patterns
Random blog article
Googling for "Program to an interface, not an implementation" will yield many useful resources.
Have the domain model layer define interfaces for the methods you'll need to call, and POCOs for the objects that need to be returned by those methods. The data layer can then implement those interfaces by pulling data out of your data store and mapping it into the domain model POCOs.
Any domain-level class that requires a particular data-access service can just depend on the interface via constructor arguments. Then you can leverage a dependency-injection framework to build the dependency graph and provide the correct implementations of your interfaces wherever they are required.
Before writing tons of code in order to separate everything you might want to ask yourself a few questions:
Is the Domain Model truly separate from the DAL? And yes, I'm serious and you should think about this because it is exceedingly rare for an RDBMS to actually be swapped out in favor of a different one for an existing project. Quite frankly it is much more common for the language the app was written in to be replaced than the database itself.
What exactly is this separation buying you? And, just as important, what are you losing? Separation of Concerns (SoC) is a nice term that is thrown about quite a bit. However, most people rarely understand why they are Concerned with the Separation to begin with.
I bring these up because more often than not applications can benefit from a tighter coupling to the underlying data model. Never mind that most ORM's almost enforce a tight coupling due to the nature of code generation. I've seen lot's of supposedly SoC projects come to a crash during testing because someone added a field to a table and the DAL wasn't regenerated... This kind of defeats the purpose, IMHO...
Another factor is where should the business logic live? No doubt there are strong arguments in favor of putting large swaths of BL in the actual database itself. At the same time there are cases where the BL needs to live in or very near your domain classes. With BL spread in such a way, can you truly separate these two items anyway? Even those who hate the idea of putting BL in a database will fall back on using identity keys and letting the DB enforce referential integrity, which is also business logic..
Without knowing more, I would suggest you consider flattening the Data Access and Domain Model layers. You could move to a "provider" or "factory" type architecture in which the service layer itself doesn't care about the underlying access, but the factory handles it all. Just some radical food for thought.
You should take a look at Martin Fowler's Repository and UnitOfWork patterns to use interfaces in your system
Until now I have seen that application can be well layered into three layers: Presentation-->Logic-->Data--and Entities (or Bussines Object). In the Logic Layer case you can use some pattern such as Transaction Script or Domain Model I'm supposing you're using this last. The domain model can use a Data Mapper for interacting with the data layer and create business objects, but you can also use a Table Module pattern.
All this patterns are described in Marttin's Fowler Patterns of Enterprise Application Architecture book. Personally I use Transaction Script because it is simplest than Domanin Model.
One solution is to make your Data Access layer subclass your domain entities (using Castle DynamicProxy, for example) and inject itself into the derived instances that it returns.
That way, your domain entity classes remain persistence-ignorant while the instances your applications use can still hit databases to lazy-load secondary data.
Having said that, this approach typically requires you to make a few concessions to your ORM's architecture, like marking certain methods virtual, adding otherwise unnecessary default constructors, etc..
Moreover, it's often unnecessary - especially for line-of-business applications that don't have onerous performance requirements, you can consider eagerly loading all the relevant data: just bring the inventory items up with the order.
I felt this was different enough from my previous answer, so here's a new one.
Another approach is to leverage the concept of Inversion of Control (IoC). Build an Interface that your Data Access layer implements. Each of the DAL methods should take a list of parameters and return a Data Table.
The service layer would instantiate the DAL through the interface and pass that reference to your Domain Model. The domain model would then make it's own calls into the DAL, using the interface methods, and decide when it needs to load child objects or whatever.
Something like:
interface IDBModel {
DataTable LoadUser(Int32 userId);
}
class MyDbModel : IDBModel {
DataTable LoadUser(Int32 userId) {
// make the appropriate DB calls here, return a data table
}
}
class User {
public User(IDBModel dbModel, Int32 userId) {
DataTable data = dbModel.LoadUser(userId);
// assign properties.. load any additional data as necessary
}
// You can do cool things like call User.Save()
// and have the object validate and save itself to the passed in
// datamodel. Makes for simpler coding.
}
class MyServiceLayer {
public User GetUser(Int32 userId) {
IDBModel model = new MyDbModel();
return new User(model, userId);
}
}
With this mechanism, you can actually swap out your db models on demand. For example, if you decide to support multiple databases then you can have code that is specific to a particular database vendors way of doing things and just have the service layer pick which one to use.
The domain objects themselves are responsible for loading their own data and you can keep any necessary business logic within the domain model. Another point is that the Domain Model doesn't have a direct dependency on the data layer, which preserves your mocking ability for independent testing of business logic.
Further, the DAL has no knowledge of the domain objects, so you can swap those out as necessary or even just test the DAL independently.