Let’s say that I have a Domain assembly that describes the domain model, and it has a class called product:
public class Product
{
public int Id { get; set; }
public string Name { get; set; }
}
I have also another assembly that is the web application running with this domain model. Now I want to create a form to create new products and have some validation on the attributes. The easiest way to do this is to use DataAnnotations on the class. However this results in that the domain model now contains metadata about form validation, which is not a very clear separation of concerns.
It is possible to have the MetadataType attribute for the class but I see this as no better. Suddenly your domain model class has a dependency on the form validation metada class.
Another way is to create a CreateProductForm class and add the required attributes there, and do mapping between the classes. However this creates some overhead as you need to maintain these classes seperately and changes in one might break the other. It might be desirable in some scenarios to do that, but in some others it might just create extra work (imagine that you have an Address class, for example).
UPDATE: some people have suggested that I use AutoMapper for this, which I’m already aware of. AutoMapper just makes mapping simpler and easier, does not actually solve the problem of having to maintain two separate classes which will be almost identical. My preference would be to only create the form classes when there is a distinct need for it.
Is there a straightforward to declare the annotations within the web assembly, without creating unnecessary dependencies for the domain assembly?
Why wouldn’t you have DataAnnotations on your domain classes. If there is something that is Required, then I think it’s perfectly valid to mark it as required in the domain.
Other DataAnnotations such as StringLength, Range etc, all to me perfectly valid things to decorate your domain entities with.
Implementing IValidableObject is also a perfectly acceptable thing for domain object to do IMHO.
I wouldn’t go putting UI stuff on them such as UIHint though or annoations describing the formatting of the property. That would be bad.
Normally I avoid displaying domain classes on the user interface, and use ViewModel classes with a mapping tool such as AutoMapper etc to map from one to the other. The ViewModel class has the annoations of the domain class with perhaps additional UI specific annotations.