Onion Architecture - Domain Model methods that require information from Infrastructure - c#

I'm just getting started with DDD and implementing the Onion Architecture.
I'm making an invitation system, where a super user can invite another user by email to his company. However when creating the invitation, I want to ensure that the user is not already created in the system. I want to do that by checking if there's any record in the database with that email. I'm using Entity Framework to handle the database context.
And I've made a repository for both Invitation and UserAccount, that contain methods to find items based on an Id.
I need to use the DB context in order to see if the invitation is still valid, but since the method is declared in the Domain Layer, I can't really figure out how to do it, without breaking the design pattern. The Domain layer should not know anything about the persistence layer.
I thought about injecting the IUserAccountRepository and then executing the required methods in order to complete the Accept() method, but I'm afriad this is wrong.

The Domain layer should not know anything about the persistence layer.
That's right - the domain layer should not know about persistence.
But that constraint doesn't apply to the application layer.
In other words, we design our domain model interface so that it "asks for" the information that we (might) need to successfully compute the next state of the model, and the application has the problem of figuring out where that information comes from.
public UserAccount Accept(Guid userId, Boolean userExistsInDatabase)
What you will see in some designs, is that instead of passing in the answer to the question, we'll pass in the capability of asking the question, and let the model decide for itself whether the question should be asked and what to do with the answer
public UserAccount Accept(Guid userId, Roster roster)
In this case, Roster would be an interface defined by your model, that accepts some piece of information that the model already has and reports back some other piece of information that your model understands. Then your application would provide an implementation of this interface when invoking the method.
Passing values across the boundaries is a bit more "pure", in that the model code doesn't need to know anything about the failure modes of the Roster -- all of that code would instead live in the application layer.

It's OK to use Contracts in your Domain Services.
"IUserAccountRepository" is a Contract that we create in the domain and the domain service doesn't know about implementation.
So Do not worry about that it's right

Related

Design pattern for implementing LastUpdated and UpdatedBy

I have been pondering this problem for a while now and cannot think of an acceptable solution. I have an application that is planned to become very large. Because of this I am trying to make it modular. It is based on MVC4. I have not decided on using a ORM or mapping everything myself. I would like to have the following structure:
----------------------
| Database
----------------------
| Data/Data Access Layer (Class Library) (Objects reside here)
----------------------
| Core MVC Project (User and Session are stored here)
----------------------
| MVC Modules
I want to keep the validation of the UpdatedBy field as close to the database as possible, possibly in the Data/Data Access layer. The problem is I want to store the user in the Session and do the validation in the class library (where there is no Session). I also want to avoid as much as possible passing the user all over the place. Is there a way to store the user in the Session and have the Data Access layer access that info without being passed the user? Anybody have any recommendations on how to do this elegantly?
EDIT: I want to keep validation, and CRUD activities as close to the Data layer as possible where the Core MVC project just calls Save() on an object and the Data layer validates the object, figures out what user modified or created it and saves it to the DB.
EDIT 2: It is imperative that the Data layer have absolutely no dependencies in the MVC layer.
The LastUpdated can easily be implemented with a Trigger on DB Insert/Updates, but the UpdatedBy is a bit trickier.
A key question is "does your business layer require knowledge of who is using it?" If so, then the interfaces can be designed to require that a Username is provided when making actions. If not then you need to make the data accessible from within/behind the business layer, but without being explicitly provided to it (such as with Dependency Injection, or by providing a Context that is availalble throughout).
You could consider creating a seperate audit-trail using ActionFilters around your controller actions, which provides easy access to the Session, and can create a running history of actions your users take. This may or may not correctly 100% to your database records, but does provide a clear history of the actions of the application--which is valuable in its own right.
You could also consider using a Command pattern, whereby the application generates specific commands (e.g. an UpdateWidgetName command) that are enacted on the business/data layer. In some regards this is how MVC already works, but having an explicit Command which captures the user and date is still a useful addition to your business layer.
Also be aware of the shortcomings of keeping this on the record itself. You'll only know who last edited the record--you won't be able to tell specifically what they edited, or who edited it previously. For relatively simple scenarios this is usually sufficient, but it is far from providing actual historical data for the record.
If you really want 100% auditing you should look at the Event Sourcing design pattern, where effectively if an action isn't audited then it didn't happen. It's a very different paradigm from the typical CRUD approach, but is very powerful (albeit more complicated to design initially)
One other note: consider seperating your business and persistence code into two layers. Tying them together makes the business logic tightly coupled to persistence (bad), which will prevent it from being reused. Look into implementing a Repository which is dedicated to persisting and retrieving your business objects. It pays off.
If you use a structure like this in your application, you can define some core interfaces that can be used throughout your application (like ICurrentUserProvider), and then you can implement those interfaces in the parts of your application where they are best implemented, without creating a tight coupling or dependency to that specific part of the application.
When your web project is initialized, it can initialize your DI framework so that your controllers get their dependencies injected into them. That way your controller gets the Business Layer services it needs, and those Business Layer services have the data-layer implementations they need (without actually having a direct dependency on them), and the data access object gets the service that can tell it who the current user is (without depending directly on the MVC layer).

Who get Access to the Database in MVVM Pattern

After reading many articles about this i'm still not really sure what's the best solution could look like
Some telling me the ViewModel and the Model should get access to Database other are telling me only the Model should get access.
Further more does this also really depends on the way i connect to my database?
if i use a Repository should really both get access to it and
what if i want to use a EF should now only the "Model" are able to perform Database interactions?
Or does anybody know's a general rule about who should when are able to get access to the Database?
You should devide your application in Layers
UI layer - Responsible for the graphic part of your application containing your Views and ViewModels.
BusinessLayer - This is the layer your UI layer speaks with. Containing all logic and and it functions as gateway to your database. This contains your model and domain model.
Database layer - This layer is responsible for all communication to your database, generally providing generic methods for your Business layer to access and persist your data.
You should keep a clear seggregation between your UI and data.
There are offcourse many variations on this setup.

Validation in a layered application

I'm wondering what's the best way to do validation of database constraints (e.g. UNIQUE) in a ASP.NET MVC application, build with DDD in mind, where the underlying layers are Application Layer (application services), Domain Layer (domain model) and Infrastructure Layer (persistance logic, logging, etc.).
I've been looking through lots of DDD samples, but what many of them doesn't mention is how to do validation in the repository (I suppose that this is where this type of validation fits). If you know of any samples doing this, please share them it will be much appreciated.
More specific, I have two questions. How would you perform the actual validation? Would you explicitly check if a customer name already exists by querying the database, or would you try inserting it directly in the database and catching the error if any (seems messy)? I prefer the first one, and if choosing this, should it be done in the repository, or should it be the job of a application service?
When the error is detected, how would you pass it to ASP.NET MVC so the user can be informed nicely about the error? Preferably using the ModelStateDictionary so the error is easily highlighted on the form.
In the N-Lyered app by Microsoft Spain, they use the IValidatableObject interface and the most simple property validation is placed on the entity itself, such as:
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
var validationResults = new List<ValidationResult>();
if (String.IsNullOrWhiteSpace(this.FirstName))
validationResults.Add(new ValidationResult(Messages.validation_CustomerFirstNameCannotBeNull, new string[] { "FirstName" }));
return validationResults;
}
Before the entity is persisted, the Validate message is called to ensure that the properties are valid:
void SaveCustomer(Customer customer)
{
var validator = EntityValidatorFactory.CreateValidator();
if (validator.IsValid(customer)) //if customer is valid
{
_customerRepository.Add(customer);
_customerRepository.UnitOfWork.Commit();
}
else
throw new ApplicationValidationErrorsException(validator.GetInvalidMessages<Customer>(customer));
}
The ApplicationValidationErrorsException can then be catched in the MVC application and the validation error messages can be parsed and inserted into the ModelStateDictionary.
I could add all the validation logic into the SaveCustomer method, e.g. querying the database checking if a customer already exists using a given column (the UNIQUE one).
Maybe this is okay, but I would rather that the validator.IsValid (or something similar) would do this for me, or that validation is performed once again in the Infrastructure layer (if it belongs here, im not sure).
What do you think? How do you do it? I'm very interesting in gaining more insight into different validation techniques in layered applications.
Possible solution #1
In the case where the validation logic can't be done in the presentation layer (like Iulian Margarintescu suggests) and needs to be done in the service layer, how would you pass validation errors up to the presentation layer?
Microsoft has a suggestion here (see listing 5). What do you think about that approach?
You mention DDD, yet there is a lot more to DDD than entities and repositories. I assume you are familiar with Mr Eric Evans's book Domain Driven Design and i would strongly suggest you re-read the chapters about strategic design and bounded contexts. Also Mr Evans has a very nice talk called "What i've learned about DDD since the book" that you can find here. Talks about SOA, CQRS and event sourcing from Greg Young or Udi Dahan also contain a lot of information about DDD and applying DDD. I must warn you that you might discover things that will change the way you think about applying DDD.
Now for your question about validation - One approach might be to query the db (using an Ajax call that is directed to an app service) as soon as the user types something in the "name" field and try to suggest an alternative name if the one he entered already exists. When the user submits the form, try to insert the record in the db and handle any duplicate key exception (at the repository or app service level) . Since you are already checking for duplicates ahead of time the cases where you get an exception should be fairly rare so any decent "We are sorry, please retry" message should do since, unless you have A LOT of users they will probably never see it.
This post from Udi Dahan also has some information on approaching validation. Remember that this might be a constraint you are imposing on the business instead of a constraint that the business imposes on you - Maybe it provides more value for the business to allow customers with the same name to register, instead of rejecting them.
Also remember that DDD is a lot more about business than it is about technology. You can do DDD and deploy your app as a single assembly. Layers of client code on top of services on top of entities on top of repositories on top of databases have been abused so many times in the name of "good" design, without any reasons for why it is a good design.
I'm not sure this will answer your question(s) but i hope it will guide you to find the answers yourself.
I'm wondering what's the best way to do validation of database constraints (e.g. UNIQUE)
and if choosing this, should it be done in the repository, or should it be the job of a application service?
It depends on what you are validating.
If it's an aggregate root creation you are trying to validate - then there is nothing more global than app itself that "holds" it. In this case, I apply validation directly in repository.
If it's an entity, it lives in aggregate root context. In this case I'm validating entity uniqueness in aggregate root itself against all the other entities in this particular aggregate root. Same goes for value objects in entities/roots.
P.s. repository is a service. Do not look at services as universal store for necessary but hard to name properly code. Naming matters. The same goes with names like "Helpers", "Managers", "Common", "Utilities", etc. - they are pretty much meaningless.
Also - you don't need to pollute your code base with pattern names: AllProducts > ProductRepository; OrderRegistrator > OrderService; order.isCompleted > IsOrderCompletedSpecification.IsSatisfiedBy.
More specific, I have two questions. How would you perform the actual validation? Would you explicitly check if a customer name already exists by querying the database, or would you try inserting it directly in the database and catching the error if any (seems messy)?
I would query the database. Although, if high performance is a concern and customer name availability is only thing that database should enforce - I would go with relying on database (1 less round trip).
When the error is detected, how would you pass it to ASP.NET MVC so the user can be informed nicely about the error? Preferably using the ModelStateDictionary so the error is easily highlighted on the form.
Usually it is not a good idea to use exceptions for controlling flow of application, but, since I want to enforce UI to show only available things that can be done, I'm just throwing exception in case validation fails. In UI layer, there's a handler that neatly picks it up and spits out in html.
Also - it is important to understand what is the scope of command (e.g. product ordering command might check 2 things - if customer ain't debtor and if product is in store). If command has multiple associated validations, those should be coupled together so UI would receive them simultaneously. Otherwise it would lead to annoying user experience (going through multiple errors while trying to order that damn product over and over again).

How to create rich domain objects while maintaing persistence ignorance?

First off, I am using web forms without any ORM framework.
I have been struggling with how to make my domain objects as "smart" and "rich" as they can be without allowing them access to my service and repository layer. My most recent attempt was in creating a model for gift certificates for a online store.
The main recurring issues that I am seeing is that:
More and more logic keeps being introduced in the service layer. All the calls to the repository must pass through the service layer and each time the parameters are validated (eg - exists in db, etc). As a result my service layer is growing, but my domain objects just have some simple contractual validations. Even object validation is in the service layer since if the ID of the item is null, it will check the db to ensure that the code is unique. IHMO, the consumer of the system should not care if the functionality they need deals with persistence or not.
I have a separate POCO for transaction log entries for when a gift certificate is redeemed. I assume that I should put a list or collection of these transactions as a property of my Gift Certificate model, but I am still unsure of when that property should be filled. Do I add a separate method on the service for loading the transactions into a object on demand (eg - LoadTransactions(gc object)) or should the transactions be automatically loaded any time a existing gift certificate or list of gift certificates are requested (or maybe a option in the getGCs to load transactions as well)
What about computed fields like "Available Balance"... should I even have properties like this on my object? Anytime I am working with the object, I will need to keep updating that property to insure it is up to date. Right now I simply have a service method GetBalanceByCode(gc code).
Even actions like redeeming a gift certificate are basically 100% data-centric (take some input parameters, validate them and add a transaction log entry to db).
More and more logic keeps being
introduced in the service layer (...)
Even object validation is in the
service layer (...)
Validation is not the best candidate as domain model element. Input (my personal preference is that it's represented as commands) should be validated at application service level. Domain logic should model how business work and assume that all the arguments are valid. Good candidates for domain logic are computations for example: you want to have them in one single place and have them well tested.
I have a separate POCO for transaction
log entries for when a gift
certificate is redeemed.
This kind of object is known as Event. You can learn about Events from Eric Evans 'What I learnt since the Blue Book' presentation. Event is basically an entity which is immutable. Events are quite often aggregates on their own because usually there's lots of them. By making them aggregates, you don't have any problems with lazy loading them as part of other objects's collection.
What about computed fields like
"Available Balance"... should I even
have properties like this on my
object?
Computed properties are kind of logic that naturally fits in domain model, however it's debatable if a better approach is to compute the value each time or compute it when object changes and persist it in the DB.
Even actions like redeeming a gift
certificate are basically 100%
data-centric (take some input
parameters, validate them and add a
transaction log entry to db).
This action would be modeled as creating a CertificateRedeemed event. This event would be probably created by Certificate aggregate or some other object. This blog post by Udi Dahan can be helpful
This is not an entirely easy question to answer given the fact that domain models are very subjective, and rely a lot on your...well, domain. It sounds like you are actually creating something similar to The Onion Architecture (and Part 2) described by Jeffery Palermo. This is not a bad pattern to use, though DDD purists will tell you it leads to "anemic" domain models (where your domain objects are basically Data holders with no behavior). The thing is, that may be exactly what you need in your scenario. A "full, rich" domain model may be overkill for what you are doing (and given your last bullet point it sounds like that could be the case).
You may not need a domain model for your system at all. You could be well served with some View Models (that is simple data models to describe your view) and have your UI send some DTOs to through your services to put the data in the database. If you find something that requires a more complex approach, then you can apply a richer domain model to that component. Also remember that you don't necessarily have one domain model in your system. There can, and in many cases should, be different models that describe things differently (often grouped into Bounded Contexts). The overall goal of DDD is to simplify otherwise complex systems. If its causing you additional complexity, then you may be taking the long way round.
There is an approach called DCI (data-context-interactions) which is supposed to be alternative to the old school OOP. Although it does not address explicitly the issue of persistence ignorance, your question brought it to my mind, because it deals with similar issues.
In DCI domain objects are small data-holders with only a little logic, like in your case, and interactions between them are implemented separately. The algorithm of interaction is not spread through small methods of several objects, but it is in one place, which might make it more lucid and understandable.
I think it is still rather academic thing than a solution we should start implementing tomorrow, but someone who comes across this question might be interested.

How to handle input and parameter validation between layers?

If I have a 3 layer web forms application that takes user input, I know I can validate that input using validation controls in the presentation layer. Should I also validate in the business and data layers as well to protect against SQL injection and also issues? What validations should go in each layer?
Another example would be passing a ID to return a record. Should the data layer ensure that the id is valid or should that happen in BLL / UI?
You should validate in all layers of your application.
What validation will occur at each layer is specific to the layer itself. Each layer should be safe to send "bad" requests to and get a meaningful response, but which checks to perform at each layer will depend on your specific requirements.
Broadly:
User Interface - Should validate user input, provide helpful error messages and visual clues to correcting them; it should be protecting your lower layers against invalid user input.
Business / Domain Layer - Should check arguments to methods are valid (throwing ArgumentException and similar when they are not) and should check that operations are possible within the constraints of your business rules; it should be protecting your domain against programming mistakes.
Data Layer - Should check the data you are trying to insert or update is valid within the context of your database, that it meets all the relational constraints and check constraints; it should be protecting your database against mistakes in data-access.
Validation at each layer will ensure that only data and operations the layer believes to be correct are allowed to enter. This gives you a great deal of predictability, knowing information had to meet certain criteria to make it through to your database, that operations had to be logical to make it through your domain layer, and that user input has been sanitized and is easier to work with.
It also gives you security knowing that if any of your layers was subverted, there is another layer performing checks behind it which should prevent anything entering which you don't want to.
Should I also validate in the business and data layers as well to protect against SQL injection and also issues?
Yes and Yes.
In your business layer code, you need to validate the input again (as client side can be spoofed), and also for your business logic, making sure the entries make sense for your application.
As for the data layer - you again need to ensure data is valid for the DB. Use parametrized queries as this will pretty much ensure no SQL injection will happen.
As for your specific question regarding the ID - the DB will know if an ID exists or not. Whether that is valid or not, depends on whether it has meaning for your business layer or not. If it purely a DB artefact (not part of your object model), than the DB needs to handle it, if it is a part of your object model and has significance to it, the business layer should handle it.
You absolutely need to validate in your business and data layers. The UI is an untrusted layer, it is always possible for somebody to bypass your client-side validation and in some cases your server-side UI validation.
Preventing SQL injection is simply a matter of parameterizing your queries. The phrase "SQL Injection" shouldn't even exist anymore, it's been a solved problem for years and years, and yet every day I see people writing queries using string concatenation. Don't do this. Parameterize the commands and you will be fine.
One of the main reasons you separate your app into multiple tiers is so that each tier is reusable. If individual tiers don't do their own validation, then they are not autonomous and you don't have proper separation of concerns. You also can't do any thorough testing without individual components doing built-in validation.
I tend to relax these restrictions for classes or methods that are internal or private because they're not getting directly tested or used. As long as the public API is fully-validated, private APIs can generally assume that the class is in a valid state.
So, basically, yes, every layer, in fact every public class and method needs to validate its own data/arguments.
Semantic validation, like checking whether or not a particular Customer ID is valid, is going to depend on your design requirements. Obviously the business layer has no way of knowing whether or not an ID exists until said ID actually hits the data layer, so it can't perform this check in an advance. Whether it throws an exception for a missing ID or simply returns null/ignores the error depends on exactly what the class/method is designed to do.
However, if this ID needs to be in a special format - for example, maybe you're using specially-coded account numbers ("R-12345-A-678") - then it does become the responsibility of the domain/business layer to validate the input and make sure it conforms to the correct format, especially if the consumer of your business class is trying to create a new account.
No layer should trust data coming from another layer. The analogy I use for this is one of fiefdoms. Say you want to send a message to the king. If the message is not in the proper format it will be rejected before it ever gets to his ears. You could continue to send messages until you eventually get the format right or you could use an emissary. The job of the emissary is to help you verify that your message will be in the acceptable format so that the king will hear it.
Each layer in a system is a fiefdom. Each layer acts as an emissary to the layer to which it will send data by verifying that it will be accepted. No layer trusts data coming from outside that layer (no one trusts messages from outside the fiefdom). The database does not trust the middle layer. The middle-layer does not trust the database or the presentation layer. The presentation does not trust the user or the middle layer.
So the answer is that absolutely you should check and re-check the data in each layer.
Short answer: yes.
Validate as input gets received in each new layer and before it gets acted upon, generally I validate such input just before it gets used or passed on to the next layer (javascript checks if it's a valid email and free of malicious input, likewise the business layer does before constructing a query using it.)
To your last question: if the ID returns a record, then it is valid, and you'd have to find the record's id to confirm whether or not it is valid, so you'd be making a lot of unnessecary lookups if you were to try that.
I hope that helps.
I do all of my validation at the Presenter layer in the Model-View-Presenter. Validation is somewhat tricky because it's really a crosscutting concern so many times.
I prefer to do it at the presenter layer because I can then shortcircuit calling to the model.
The other approach is to do the validation in the model layer but then the issue of communication of errors because you cannot easily inform other layers of errors aside from exceptions. You can always pack exceptions with data or create your own custom exception that you can attach a list of error messages or similar construct to but that always seem dirty to me.
Later when I expose my model through a web service I will implement double validation checking both in the Presenter and in the Model since it will be possible to jump the presenter layer if you call the web service. The other big advantage to this is that it decouples my validations for the presenter layer from the model since the model might only require raw validation of types to match the database whereas users of my UI I want more granular rules of what they input not just that they physically can.
Other questions: the sql injection portion that is a model concern and should not be in any middle layers. However most sql injection attacks are completely nullified when text fields don't allow special characters. The other part of this is you should almost always be using parametrized sql which makes sql injection not usable.
The question on the ID that's a model concern either it can get a record with that ID or it should return null or throw an exception for record not found depending on what convention you wish to establish.

Categories