Using AutoMapper to load entities from the database? - c#

Most of what I've read (e.g. from the author) indicates that AutoMapper should be used to map an an entity to a DTO. It should not load anything from the database.
But what if I have this:
public class Customer {
public int Id { get; set; }
public string Name { get; set; }
public virtual ICollection<Order> Orders { get; set; }
}
public class CustomerDto {
public int Id { get; set; }
public string Name { get; set; }
public IEnumerable<int> OrderIds { get; set; } // here is the problem
}
I need to map from DTO to entity (i.e. from CustomerDto to Customer), but first I must use that list of foreign keys to load corresponding entities from the database. AutoMapper can do that with a custom converter.
I agree that it doesn't feel right... but what are the alternatives? Sticking that logic into a controller, service, a repository, some manager class? All that seems to be pushing the logic somewhere else, in the same tier. And if I do that, I must also perform the mapping manually!
From a DDD perspective, the DTO should not be part of the domain. So AutoMapper is also not part of the domain, because it knows about that DTO. So AutoMapper is in the same tier as the controllers, services, etc.
So does it make sense to put the DTO-to-entity logic (which includes accessing the database, and possibly throwing exceptions) into an AutoMapper mapping?
EDIT
#ChrisSimon's great answer below explains from a DDD perspective why I shouldn't do this. From a non-DDD perspective, is there a compelling reason not to use AutoMapper to load from the db?

To start with, I'm going to summarise my understanding of Entities in DDD:
Entities can be created - often using a factory. This is the start of their life-cycle.
Entities can be mutated - have their state modified - by calling methods on the entity. This is how they progress through their lifecycle. By ensuring that the entity owns its own state, and can only have its state modified by calling its methods, the logic that controls the entity's state is all within the entity class, leading to cleaner separation of business logic and more maintainable systems.
Using Automapper to convert from a Dto to the entity means the entity is giving up ownership of its state. If the dto is in an invalid state and you map that directly onto the entity, the entity may end up in an invalid state - you have lost the value of making entities contain data + logic, which is the foundation of the DDD entity.
To make a suggestion as to how you should approach this, I'd ask - what is the operation you are trying to achieve? DDD encourages us not to think about CRUD operations, but to think about real business processes, and to model them on our entities. In this case it looks like you are linking Orders to the Customer entity.
In an Application Service I would have a method like:
void LinkOrdersToCustomer(CustomerDto dto)
{
using (var dbTxn = _txnFactory.NewTransaction())
{
var customer = _customerRepository.Get(dto.Id);
foreach (var orderId in dto.OrderIds)
{
var order = _orderRepository.Get(orderId);
customer.LinkToOrder(order);
}
dbTxn.Save();
}
}
Within the LinkToOrder method, I would have explicit logic that did things like:
Check that order is not null
Check that the customer's state permits adding the order (are they currently active? is their account closed? etc.)
Check that the order actually does belong to the customer (what would happen if the order referenced by orderId belonged to another customer?)
Ask the order (via a method on the order entity) if it is in a valid state to be added to a customer.
Only then would I add it to the Customers Order's collection.
This way, the application 'flow' and infrastructure management is contained within the application/services layer, but the true business logic is contained within the domain layer - within your entities.
If the above requirements are not relevant in your application, you may have other requirements. If not, then perhaps it is not necessary to go the route of DDD - while DDD has a lot to add, its overheads are generally only worth it in systems with lots of complex business logic.
This isn't related to the question you asked, but I'd also suggest you take a look at the modelling of Customer and Order. Are they both independent Aggregates? If so, modelling Customer as containing a collection of Order may lead to problems down the road - what happens when a customer has a million orders? Even if the collection is lazy loaded, you know at some point something will attempt to load it, and there goes your performance. There's some great reading about aggregate design here: http://dddcommunity.org/library/vernon_2011/ which recommends modelling references by Id rather than reference. In your case, you could have a collection of OrderIds, or possibly even a completely new entity to represent the link - CustomerOrderLink which would have two properties - CustomerId, and OrderId. Then none of your entities would have embedded collections.

Related

How to set Id of Entity object when getting it from Repository

In Domain-Driven Design, how can I hydrate the Id property when I retrieve an entity from a repository? When I create an entity for the first time (before it is persisted), I can generate a unique ID in the entity's constructor. But when I retrieve an entity from the repository, it already has an ID. How do I set the Id property in this case? Passing the ID to the entity's constructor doesn't feel right to me, but maybe it is the correct approach?
I am not using an object-relational mapping (ORM) tool.
public interface IPersonRepository
{
Person GetById(long id);
}
public abstract class Entity
{
public long Id { get; private set; }
protected Entity()
{
Id = // Generate a unique Id with some algorithm.
}
}
public sealed class Person : Entity
{
//...
}
When I CREATE the Entity for the first time (before its persistence), I can generate a unique id in Entity's constructor...
which may not be a good idea. Non deterministic data (like time, or copies of remote mutable state) should be inputs to your domain model. In practice, you will often get away with it; but that alone doesn't make it a good idea.
The usual answer is that the repository will fetch the persisted representation of the information (a DTO, for example), and hand that off to a factory whose purpose is the construction of the entity.
So the identity of the entity becomes just another piece of information passed from the repository to the factory.
Now, "factory" here is just another life cycle pattern; and it can take many different forms, including the form of constructor. In which case, the identifier would normally just be passed into the entity as an argument.
Identifiers in particular can be a bit weird, because they don't normally express business semantics. It's typical of the identifier pattern that they are opaque things that really only support equality comparison. Your entities almost never look at their own identifier to figure out what to do next.
But if your entity needs a reference to its own identifier, for whatever reason, you'll normally create that reference when you initialize the object, and leave it unchanged from that point forward (in other words, the entities identifier property is an immutable reference to an immutable value).
1) Aggregate or Entity?
I think there is some confusion in your question in terms of DDD. In general you shouldn't load entities. You should load Aggregate, through Aggregate root (which is entity), all other entities for this aggregate should be loaded automatically.
From Evans DDD:
only AGGREGATE roots can be obtained directly with database queries. All other objects must be found by traversal of associations.
Martin Fowler:
Aggregates are the basic element of transfer of data storage - you request to load or save whole aggregates.
Aggregate Root
2) How to set a Id. It's a good idea to use immutable properties. public long Id { get; private set; }, lets think we are doing things correctly when we use immutable id. Now lets go ahead and found possible ways for setting Id properly.
set id from the class method. Looks confusing to set id for existing entity (aggregate root). I don't suggest to use this option.
set id from constructor. Why not? You set the Id during the creation of the entity (aggregate root). From Evans DDD:
A public constructor must follow the same rules as a FACTORY: It must be an atomic operation that satisfies all invariants of the created object.
factory. From Evans DDD:
Complex assemblies, especially of AGGREGATES, call for FACTORIES
set id during deserialisation. Is clear and simple way. I would chose this one. I would store Id and other data together (it's common practise). GetById(long id); returns Person which already had Id setted during deserialisation.

DTO vs. Domain Model, project organization

I have a project with a repository, a service layer, using EF6 and code-first POCOs. In the CustomerRepository, I am doing several projection queries that return objects.
I understand that the code-first POCO's are what would be considered "Domain Models", but if I were to do a projection query into a different model, what is that model considered? An example of this would be the CustomerOrderStats. Is that still a Domain Model, or should that be considered a DTO model?
Example
Object returned from Repository:
public class CustomerOrderStats
{
public string Name { get; set; }
public int Count { get; set; }
}
Query in the Repository
public CustomerOrderStats GetCustomerOrderStats(Guid customerGuid)
{
return customers
.Where(c => c.Guid == customerGuid)
.Select(new CustomerOrderStats
{
Name = c.Name,
Count = c.Orders.Count()
};
}
It could be either one, really. The definition of a model vs. a DTO isn't really a matter of how you organize any given framework, but rather what that object represents in the domain. If it has rich functionality or business logic or is an active part of the actual business process, it's probably a model. If, on the other hand, it's just a container of properties to move values from one place to another, it's probably a DTO.
The key here is whether the object is an active part of the business process. And a good rule of thumb here is often the name of the object.
Is it a name that non-technical business team members understand?
Is it a term they use to describe what the business does? (Even a very small part of the business)
Does it carry a meaning in the industry in general?
A DTO is generally something that exists for purely technical reasons. Component A needs to send data to Component B, but that operation is a technical one and not a business one. Data just needs to be, well, transferred. As a piece of the system, it's essentially built "from the bottom up" because it satisfies a low-level technical need.
A model describes a part of the business. It could be an element on a chart which defines the business process in non-technical terms, or an encapsulation of a business concept. As a piece of the system, it's essentially built "from the top down" because it is described generally by the business and then implemented specifically to meet that need.

DDD aggregate and entity framework. Which way is preferable?

I am little bit confused about the problem. I have an entity Product that is represented in the database. It looks like POCO. Here is example (I use attributes instead of fluent api for simplicity).
public class Product
{
[Key]
public int Id { get; set; }
//other properties that have mapping to db
}
But now I want to avoid AnemicDomainModel anti-pattern
So I am going to fill the Product model with methods and properties, that do not have mapping to db, so I should use [Ignore].
public class Product
{
[Key]
public int Id { get; set; }
[Ignore]
public object FooProperty { get; set; }
//other properties that have mapping to db
//other properties and methods that do not have mapping to db
}
I think such a way spoils my model. In this article I've found acceptable workaround. Its idea is to separate Product (domain model) and ProductState (state of product that is stored in the database). So Product is wrapper for ProductState.
I really want to know the views of other developers. Thanks a lot for your answers.
I understood that my real question sounds something like that: "Should I separate Data model and domain model? Can I change EF entities from Anemic to Rich?"
To ensure persistence ignorance of your entities, I've found EF Fluent Mapping to be better than Data Annotations. The mappings are declared in an external file, thus normally your entity doesn't have to change if something in the persistence layer changes. However, there are still some things you can't map with EF.
Vaughn's "backing state object" solution you linked to is nice, but it is an extra layer of indirection which adds a fair amount of complexity to your application. It's a matter of personal taste, but I would use it only in cases when you absolutely need stuff in your entities that cannot be mapped directly because of EF shortcomings. It also plays well with an Event Sourcing approach.
The beauty of the Entity Framework is that it allows you to map your database tables to your domain model using mappings which can be defined using the Fluent API, therefore there is no need to have separate data entities. This is in comparison to its predecessor Linq To SQL where you'd map each table to an individual data entity.
Take the following example, for the paradigm of a Student and Course - a student can take many courses, and a course can have many students, therefore a many-to-many relationship in your database design. This would consist of three tables: Student, Course, StudentToCourse.
The EF will allow you to use Fluent API mappings to create the many collections on either side of the relationship without having the intermediate table (StudentToCourse) defined in your model (StudentToCourse has no existence in a DOMAIN MODEL), you would only need two classes in your domain, Student and Course. Whereas in LinqToSQL you'd have to define all three in your model as data entities and then create mappings between your data entities and domain model resulting in lots of plumbing work open to bugs.
The argument of the anaemic vs rich domain model should have little effect on your mapping between your model and database tables, but focuses on where you place the behaviour - in either the domain model or the service layer.

Entity Framework classes vs. POCO

I have a general difference of opinion on an architectural design and even though stackoverflow should not be used to ask for opinions I would like to ask for pros and cons of both approaches that I will describe below:
Details:
- C# application
- SQL Server database
- Using Entity Framework
- And we need to decide what objects we are going to use to store our information and use all throughout the application
Scenario 1:
We will use the Entity Framework entities to pass all around through our application, for example the object should be used to store all information, we pass it around to the BL and eventually our WepApi will take this entity and return the value. No DTOs nor POCOs.
If the database schema changes, we update the entity and modify in all classes where it is used.
Scenario 2:
We create an intermediate class - call it a DTO or call it a POCO - to hold all information that is required by the application. There is an intermediate step of taking the information stored in the entity and populated into the POCO but we keep all EF code within the data access and not across all layers.
What are the pros and cons of each one?
I would use intermediate classes, i.e. POCO instead of EF entities.
The only advantage I see to directly use EF entities is that it's less code to write...
Advantages to use POCO instead:
You only expose the data your application actually needs
Basically, say you have some GetUsers business method. If you just want the list of users to populate a grid (i.e. you need their ID, name, first name for example), you could just write something like that:
public IEnumerable<SimpleUser> GetUsers()
{
return this.DbContext
.Users
.Select(z => new SimpleUser
{
ID = z.ID,
Name = z.Name,
FirstName = z.FirstName
})
.ToList();
}
It is crystal clear what your method actually returns.
Now imagine instead, it returned a full User entity with all the navigation properties and internal stuff you do not want to expose (such as the Password field)...
It really simplify the job of the person that consumes your services
It's even more obvious for Create like business methods. You certainly don't want to use a User entity as parameter, it would be awfully complicated for the consumers of your service to know what properties are actually required...
Imagine the following entity:
public class User
{
public long ID { get; set; }
public string Name { get; set; }
public string FirstName { get; set; }
public string Password { get; set; }
public bool IsDeleted { get; set; }
public bool IsActive { get; set; }
public virtual ICollection<Profile> Profiles { get; set; }
public virtual ICollection<UserEvent> Events { get; set; }
}
Which properties are required for you to consume the void Create(User entity); method?
ID: dunno, maybe it's generated maybe it's not
Name/FirstName: well those should be set
Password: is that a plain-text password, an hashed version? what is it?
IsDeleted/IsActive: should I activate the user myself? Is is done by the business method?
Profiles: hum... how do I affect a profile to a user?
Events: the hell is that??
It forces you to not use lazy loading
Yes, I hate this feature for multiple reasons. Some of them are:
extremely hard to use efficiently. I've seen too much times code that produces thousands of SQL request because the developers didn't know how to properly use lazy loading
extremely hard to manage exceptions. By allowing SQL requests to be executed at any time (i.e. when you lazy load), you delegate the role of managing database exceptions to the upper layer, i.e. the business layer or even the application. A bad habit.
Using POCO forces you to eager-load your entities, much better IMO.
About AutoMapper
AutoMapper is a tool that allows you to automagically convert Entities to POCOs and vice et versa. I do not like it either. See https://stackoverflow.com/a/32459232/870604
I have a counter-question: Why not both?
Consider any arbitrary MVC application. In the model and controller layer you'll generally want to use the EF objects. If you defined them using Code First, you've essentially defined how they are used in your application first and then designed your persistence layer to accurately save the changes you need in your application.
Now consider serving these objects to the View layer. The views may or may not reflect your objects, or an aggregation of your working objects. This often leads to POCOS/DTO's that captures whatever is needed in the view. Another scenario is when you want to publish objects in a web service. Many frameworks provide easy serialization on poco classes in which case you typically either need to 1) annotate your EF classes or 2) make DTO's.
Also be aware that any lazy loading you may have on your EF classes is lost when you use POCOS or if you close your context.

Persistance ID's and Domain Model Entities

I was curious on what peoples thoughts are on keeping the Id of a DAL entity as a property of the Domain Entity, at the absolute most a read-only property.
My first thoughts was that this is ok to do but the more I think about it the more I dislike the idea. After all the domain model is supposed to be completely unaware of the how data is persisted, and keeping and Id property on each domain model is a less-than-subtle indication. The persistence layer may be something that doesn't require primary keys, or another property exposed in the domain model may be a suitable candidate for identification, a model no. perhaps.
But then that got me thinking, for domain models that do not have a reliable means of uniquely identifying an entry in a database persistence layer, how are they to identify entries when it comes to updating or deleting?
A dictionary based on weak reference keys could do the trick; WeakDictionary<DomainEntity, PrimaryKeyType>. This dictionary would be a part of the repository implementation, whenever the client of the repository Fetch's a collection of DomainEntity a weak reference to the entity and its persistence layer Id is stored in this internal dictionary such then when comes time to return the modified entity to the repository for updating the persistence layer, the following could be done to get back the Id
PrimaryKeyType id = default(PrimaryKeyType);
if (!weakDictionary.TryGetValue(someDomainEntity, out id))
// id not found, throw exception? custom or otherwise..
// id found, continue happily mapping domain model back to data model.
The benefits of this approach as I see it, is the domain entity need not maintain its persistence layer specific id and the repository forces you to have a legitimate Domain Entity obtained either by some call to a Fetch... method or the Add/CreateNew method, else should you try to update/delete the entity it will throw an exception.
I'm aware that this probably over-engineering and I should just buckle down and get pragmatic, I was just curious on what other people thought about this.
I don't want to start another thread just for this minor question as it is somewhat related. But since it is relatively recently I have started looking into DDD (though in this case my database came first) I wondered if I could confirm that I have the right mindset for Domain Entities, here is a cut down example of my Employee domain entity.
public class Employee : DomainEntity
{
public string FirstName { get; }
public string LastName { get; }
public UserGroup Group { get; }
// etc..
// only construct valid employees
public Employee(string firstName, string lastName, SecureString password, UserGroup group);
// validate, update. (not sure about this one.. pulled it
// from an open source project, I think that names should be able to be set individually).
AssignName(string firstName, string lastName);
// validate, update.
ResetPassword(SecureString oldPassword, SecureString newPassword);
// etc..
}
Thank you!
Your proposal of using weak references has one major flaw.
As you might know, domain entities have the important characteristic in that they must have identity. This is important for comparison reasons. If two entities have the same identity, regardless of the values of their properties, then they are considered equal:
Entity1 == Entity2 ⇔ Entity1.Identity == Entity2.Identity
A typical "design pattern" would be to inherit all entities from a DomainEntity<T> abstract class, which overrides the comparison of these objects and compares by identity.
Now, consider your approach of using a weak reference look up. Let's take an example:
You fetch an Entity1, say the "Reegan Layzell" user, from a repository. Then you fetch the exact same "Reegan Layzell" entity from the repository again as Entity2. You now have the same entity in your domain in two objects. But they have difference references (of course).
When comparing, these entities will not be considered equal in your domain.
I admire your fear of introducing database concerns into your domain model, but propagating the database ID into your entities is hardly going to affect the quality of your models and it will save you a lot of trouble. Like you said, we need to be pragmatic.
With regards to your Employee example: Does AssignName really make sense? In reality, can an employee's name really change after creation? Other than that, it looks like you have the right idea. I highly recommend you watch this: Crafting Wicked Domain Models by Jimmy Bogard.

Categories