When implementing DDD aggregates I usually have them expose methods that represent business functions and then those functions are responsible for modifying internal state. E.g.
public class Order
{
public int Id { get; private set; }
public IEnumerable<LineItem> LineItems { get; private set; }
public void AddLineItem(...) {...}
public void Ship() {...}
public void Cancel() {...}
}
When using EF6 or NHibernate this works well because the context/session can detect all insertions/deletes/updates of child entities. However, with EF7 I need to explicitly instruct the change tracker about such changes. E.g. when AddLineItem() adds a new line item to the LineItems collection, we must either manually add it to a DBSet on the context or inform the change tracker that the state for that line item was Added.
This means my domain objects must have an explicit dependency on Entity Framework and I must now somehow pass around references to the context (or change tracker) when calling business functions.
Is this something I should simply work around for the moment, on the basis that EF7 will ultimately have the same capabilities as EF6/NHibernate? Or is there a way to have rich domain objects without this dependency?
This can be solved by using dependency injection. This would allow separation of your domain objects from your ORM of choice (plus all the other benefits of dependency injection). There is no single, absolutely correct answer for how exactly you separate concerns in your code.
Related note: the behavior of .Add() will be changing in EF7 - beta 8 (See PR#2979). The change tracker will now include all "children" entities when you call .Add for a parent item.
Related
I am working on an application with multiple modules. I created tables for different modules under different schema in same database and all user related tables in the default schema. I feel like more confused after reading more about dbcontext, unit of work and repository pattern. I started creating one dbcontext and realized a logged in user need few number of tables but by calling the constructor, it bring everything into memory. Later I thought of creating multiple dbcontexts, but I have to include user related tables in all dbcontexts.
As a third option, I start working with unitofwork and repository pattern. Many articles were telling it is just another abstraction on top of EF with DBContext and DBSet. I still continued working and realized that I will have hundreds of repositories and once I add all of them into unitofwork and call the constructor, again everything will be loaded into memory. I am totally confused on which approach best suits for my need. Each controller need only the specific tables repositories and user tables repositories for the CRUD operations, but by doing above steps, will it cause performance issues?
My unitofwork is as below
using DemoApp.Core;
using DemoApp.Core.Repositories;
using DemoApp.Persistence.Repositories;
namespace DemoApp.Persistence
{
public class UnitOfWork : IUnitOfWork
{
private readonly DemoAppContext _context;
public UnitOfWork(DemoAppContext context)
{
_context = context;
Ones = new OneRepository(_context);
Twos = new TwoRepository(_context);
}
public IOneRepository Ones { get; private set; }
public ITwoRepository Twos { get; private set; }
public int Complete()
{
return _context.SaveChanges();
}
public void Dispose()
{
_context.Dispose();
}
}
}
And the controller
using DemoApp.Core;
using DemoApp.Core.Domain;
using DemoApp.Persistence;
using System;
using System.Linq;
using System.Web.Mvc;
namespace DemoApp.Controllers
{
public class HomeController : Controller
{
private readonly IUnitOfWork _unitOfWork;
public HomeController(IUnitOfWork unitOfWork)
{
_unitOfWork = unitOfWork;
}
public ActionResult Index()
{
var result = _unitOfWork.Ones.GetAll();
return View(result);
}
}
}
Having a single, large context will not load entities into memory on construction, but it will resolve the entity mappings which can take a few seconds in very large contexts for the first load. Bounded contexts suit very large systems where you can split off related entities, or keep "heavy" or time sensitive entities separate from the main use context.
I use a pattern with bounded contexts that uses an attribute typed to the Context in question to mark which entity type configurations apply to what context. This accommodates using smaller, read-only suited entity definitions. I'd only really recommend this for very large entity sets though. By utilizing deferred execution and .Select() expressions to pull just the data needed when it's needed, using multiple, bounded entity declarations isn't typically needed.
The argument for using Unit of Work & Repository patterns is primarily around enabling unit testing. I do not recommend using Generic repositories (repository per entity) but rather utilizing a Repository pattern much in the way you would utilize a Controller pattern. Each repository serves an area of an application with methods to retrieve, create, and delete entities relevant to that area. Tying a repository to a single entity leads to a lot of boiler-plate code, or generic operations that don't apply to all entities equally. It makes your code less flexible and ultimately harder to read. In most cases you should be utilizing the relationships mapped out between entities, so a single repository can manage retrieving and acting upon all relevant entities for a particular screen for example rather than shifting between lots of different repositories to try and load related data. I use the DbContextScope UoW pattern by Mehdime as it facilitates both read/write and read-only scopes across repositories/helpers, and negates the need to inject a dbcontext/UoW wrapper into the repositories. This enables having multiple UoW scopes in a request vs. scoping a DbContext/UoW instance to a request or manually messing around with lifetime scopes if your container supports that. In any case it's worth having a look at as an option. Mehdime's implementation is for EF 6.x, while there are forks available for EF Core.
It seems to me that almost by default all code first POCO's should have private setters for their primary key a.k.a. auto-generated Id.
Like this -
public int id { get; private set; }
Is this an incorrect assumption? I do not want my API to allow setting of an auto-generated column.
Exposing a public setter should not be an issue since it is unadvised to even expose this POCO outside the Data Access Object layer..
Exposing a POCO decorated with a specific framework's attributes, or even a POCO which discloses some kind of information regarding storage (Entity Relational Database, in this instance) is a bad practice.
Consider wrapping it in an interface and returning it as an instance of that interface. This way you get to enjoy the best of both worlds. Exposing the properties which are necessary and allowing to set only a part of them.
In any case, I do not think that EF will like the private setter thing too much.
I'm a little overwhelmed with all of the information on DDD, unit of work, domain services, app services, etc. I'm trying to figure out how a persistence-ignorant domain model ultimately gets persisted, specifically in the context of unit-of-work and Entity Framework. Let's say I have an Order aggregate root, which I am attempting to keep in my persistence-ignorant domain model (the core of my architectural onion):
public class Order : EntityBase
{
public int Id { get; private set; }
public int MarketplaceId { get; private set; }
public int CustomerId {get; set;}
public List<OrderItem> Items { get; private set; }
public List<OrderComment> Comments { get; private set; }
public void AddItem(OrderItem item) { /**add item**/ }
public void AddComment(OrderComment comment) { /**add comment**/ }
public override bool Validate() { /**validate**/ }
public void Cancel() { /**cancel**/ }
}
Let's say I have a process that updates a property on the Order entity, for example it changes the CustomerId associated with the order.
I have an IOrderRepository in my domain layer, which would have an implementation (in an outer layer) with a function like this:
Order GetOrder(int orderId)
{
//get entity framework order, items, etc.
//map to domain-layer order and return domain-layer order
}
void UpdateOrder(Order order)
{
//get ENTITY FRAMEWORK order, order items, order comments, etc.
//take DOMAIN order (passed in to this function), and update EF items fetched above
//use a single EF unit of work to commit these changes
}
There's something wrong with my approach. The UpdateOrder function seems heavy for a small change; but it also seems I have to do that if my repository isn't aware of which items on the persistence-ignorant domain model have changed. Should I be handling every type of update in a separate repository function? UpdateMarketplace(int marketplaceId), UpdateCustomer(int customerId)?
As I'm typing this, I'm also wondering...maybe the way I have it above is not too heavy? If I change one property, even though I'm doing all of the above, perhaps Entity Framework will recognize that the values being assigned are the same and will only send the one db column update to SQL?
How can I take my Order domain model (fetching is straightforward enough), perform some operation or operations on it that may be limited in scope, and then persist the model using Entity Framework?
You need to look into the Unit of Work pattern. Your UoW keeps track of the changes, so when you get your order from your repository and modify it, you call UnitOfWork.SaveChanges() which should persist all the changes.
Using Entity Framework, your DbContext is basically the Unit of Work but I would create a simpler interface around it so you can abstract it away for easier usage in your higher layers.
Regarding EF, I would recommend mapping your domain entities directly using the code first approach. I would also turn off lazy loading and all the magic stuff so you have full control and less "surprises".
Unfortunately I'm not allowed to share our code but we have all this working pretty effectively with the new EF6 Alpha 3. I would recommend you taking a look at Microsoft Spain's nlayerapp for some implementation examples. I don't agree with many of their design decisions (also, see this review), but I think you can draw some inspiration from the Entity Framework parts. Take a look at their Unit of Work implementation and especially how they have abstracted it away for easier usage in the higher layers, and how they use it in their application services.
I will also recommend looking into creating a generic repository to avoid duplicating lots of logic in your aggregate specific repositories. MS Spain has one here, but you should also take a look at this thread.
Please have a look at this SO question where I gave an example of how I've implemented UoW & Repositories.
As #Tommy Jakobsen told you, your domain entities should be your EF entities, it would avoid you to add a useless mapping layer.
Hope that helps!
You may check ASP.NET Boilerplate's Unit Of Work implementation: http://www.aspnetboilerplate.com/Pages/Documents/Unit-Of-Work
It's open source project, you can check codes. Also, you can directly use it.
I am using Entity Framework 5 with Code First approach and using Fluent API for Entity configuration. My project has one particular Product Entity which gets half of its data from the database and the other half from a Data Contract retrieved via a WCF Client (its a 3rd party system used to manage product inventory). The Data Contract is a member of the Product Entity class (property or method I haven't decided yet).
I prefer not to have any WCF Client logic contain within the Entities. I'd prefer to keep this logic in Repository code (DbContext, DbSet, etc.).
So is there a technique to hook into Entity Framework (or intercept) just after a Product Entity is retrieved from the database? I should note the Product Entity appears as a navigation property on other Entities. If a hook or intercept is possible then what that means is I can retrieve the Data Contract from the SOAP service immediately after EF loaded the Product Entity from the database. The benefit for my project is the WCF Client retrieval code does not need to be repeated throughout the application.
One idea I had was to implement IDbSet for the Data Contract and the IDbSet would be responsible for retrieving it. And then somehow trick EF into thinking its a navigation property on the Product Entity. But I wasn't sure if a database DbSet can be mixed with a non-database IDbSet all within the same DbContext. And also the other question - how would EF know to retrieve a navigation property from the IDbSet implantation? I'd prefer to know if this idea is possible before investing time into it. I'd also prefer to know where to start looking.
Please note I've been working with .NET for over 10 years but this EF5 stuff is still relatively new to me.
Thanks in advance.
-Sam
Today I found an event in the Entity Framework that seems to be what I am looking for. ObjectContext.ObjectMaterialized Event. Apparently, DbContext implements IObjectContextAdapter which in-turn exposes the ObjectContext. From there I can subscribe to the ObjectMaterialized event.
MSDN Reads:
Occurs when a new entity object is created from data in the data
source as part of a query or load operation.
The following code demonstrates how I used the ObjectMaterialized event to solve my problem in which one of my preferences was to have a central point to place the WCF client access logic.
// seperate assembly - does not use Domain.Repositories assembly
namespace Domain.Models
{
// the data contract
[DataContract]
public class ProductInventoryState
{
[DataMember]
public int StockStatus { get; set; }
[DataMember]
public IEnumerable<String> SerialNumbers { get; set; }
// etc....
}
// the entity
public class Product
{
public Guid Key { get; set; }
public string ProductCode { get; set; }
public ProductInventoryState InventoryState { get; set; }
// etc....
}
}
// seperate assembly - uses Domain.Models assembly
namespace Domain.Repositories
{
public class MainRepository : DbContext
{
public MainRepository()
{
((IObjectContextAdapter)this).ObjectContext.ObjectMaterialized += ObjectContext_ObjectMaterialized;
}
protected void ObjectContext_ObjectMaterialized(object sender, ObjectMaterializedEventArgs e)
{
if (e.Entity == null)
return;
if (e.Entity is Product)
{
Product product = (Product)e.Entity;
// retrieve ProductInventoryState from 3rd party SOAP API
using (ThirdPartyInventorySystemClient client = new ThirdPartyInventorySystemClient())
{
// use ProductCode to retrieve the data contract
product.InventoryState = client.GetInventoryState(product.ProductCode);
}
}
}
}
}
1.) You can write your own EF Provider (but that is no small task)
2.) You can attach items to the context but not save them.
The entity.State can be set as Not modified after attaching.
You could also remove such entries from Context prior to save changes
3) You can Write a repository fascade that check EF and Checks location 2 and combines the result.
On the question of navigation properties.
You would need to specify these very carefully to avoid issues. Not lazy loaded or not even modelled.
I wouldnt try and mix them personally.
You can tell EF to ignore some properties.
So you can have a Nice original POCO, but only model the bits that are on the DB.
The POCO would then collect the rest.
I use a fascade with events myself to act on KEY methods on a context/DBset.
So I can trigger events on attach , get, save etc.
good luck
I have several concerns when trying to do DDD development with EF 4.2 (or EF 4.1) code first. I've done some extensive research but haven't come up with concrete answers for my specific concerns. Here are my concerns:
The domain cannot know about the persistence layer, or in other words the domain is completely separate from EF. However, to persist data to the database each entity must be attached to or added to the EF context. I know you are supposed to use factories to create instances of the aggregate roots so the factory could potentially register the created entity with the EF context. This appears to violate DDD rules since the factory is part of the domain and not part of the persistence layer. How should I go about creating and registering entities so that they correctly persist to the database when needed to?
Should an aggregate entity be the one to create it's child entities? What I mean is, if I have an Organization and that Organization has a collection of Employee entities, should Organization have a method such as CreateEmployee or AddEmployee? If not where does creating an Employee entity come in keeping in mind that the Organization aggregate root 'owns' every Employee entity.
When working with EF code first, the IDs (in the form of identity columns in the database) of each entity are automatically handled and should generally never be changed by user code. Since DDD states that the domain is separate from persistence ignorance it seems like exposing the IDs is an odd thing to do in the domain because this implies that the domain should handle assigning unique IDs to newly created entities. Should I be concerned about exposing the ID properties of entities?
I realize these are kind of open ended design questions, but I am trying to do my best to stick to DDD design patterns while using EF as my persistence layer.
Thanks in advance!
On 1: I'm not all that familiar with EF but using the code-first/convention based mapping approach, I'd assume it's not too hard to map POCOs with getters and setters (even keeping that "DbContext with DbSet properties" class in another project shouldn't be that hard). I would not consider the POCOs to be the Aggregate Root. Rather they represent "the state inside an aggregate you want to persist". An example below:
// This is what gets persisted
public class TrainStationState {
public Guid Id { get; set; }
public string FullName { get; set; }
public double Latitude { get; set; }
public double Longitude { get; set; }
// ... more state here
}
// This is what you work with
public class TrainStation : IExpose<TrainStationState> {
TrainStationState _state;
public TrainStation(TrainStationState state) {
_state = state;
//You can also copy into member variables
//the state that's required to make this
//object work (think memento pattern).
//Alternatively you could have a parameter-less
//constructor and an explicit method
//to restore/install state.
}
TrainStationState IExpose.GetState() {
return _state;
//Again, nothing stopping you from
//assembling this "state object"
//manually.
}
public void IncludeInRoute(TrainRoute route) {
route.AddStation(_state.Id, _state.Latitude, _state.Longitude);
}
}
Now, with regard to aggregate life-cycle, there are two main scenario's:
Creating a new aggregate: You could use a factory, factory method, builder, constructor, ... whatever fits your needs. When you need to persist the aggregate, query for its state and persist it (typically this code doesn't reside inside your domain and is pretty generic).
Retrieving an existing aggregate: You could use a repository, a dao, ... whatever fits your needs. It's important to understand that what you are retrieving from persistent storage is a state POCO, which you need to inject into a pristine aggregate (or use it to populate it's private members). This all happens behind the repository/DAO facade. Don't muddle your call-sites with this generic behavior.
On 2: Several things come to mind. Here's a list:
Aggregate Roots are consistency boundaries. What consistency requirements do you see between an Organization and an Employee?
Organization COULD act as a factory of Employee, without mutating the state of Organization.
"Ownership" is not what aggregates are about.
Aggregate Roots generally have methods that create entities within the aggregate. This makes sense because the roots are responsible for enforcing consistency within the aggregate.
On 3: Assign identifiers from the outside, get over it, move on. That does not imply exposing them, though (only in the state POCO).
The main problem with EF-DDD compatibility seems to be how to persist private properties. The solution proposed by Yves seems to be a workaround for the lack of EF power in some cases. For example, you can't really do DDD with Fluent API which requires the state properties to be public.
I've found only mapping with .edmx files allows you to leave Domain Entities pure. It doesn't enforce you to make things publc or add any EF-dependent attributes.
Entities should always be created by some aggregate root. See a great post of Udi Dahan: http://www.udidahan.com/2009/06/29/dont-create-aggregate-roots/
Always loading some aggregate and creating entities from there also solves a problem of attaching an entity to EF context. You don't need to attach anything manually in that case. It will get attached automatically because aggregate loaded from the repository is already attached and has a reference to a new entity. While repository interface belongs to the domain, repository implementation belongs to the infrastructure and is aware of EF, contexts, attaching etc.
I tend to treat autogenerated IDs as an implementation detail of the persistent store, that has to be considered by the domain entity but shouldn't be exposed. So I have a private ID property that is mapped to autogenerated column and some another, public ID which is meaningful for the Domain, like Identity Card ID or Passport Number for a Person class. If there is no such meaningful data then I use Guid type which has a great feature of creating (almost) unique identifiers without a need for database calls.
So in this pattern I use those Guid/MeaningfulID to load aggregates from a repository while autogenerated IDs are used internally by database to make a bit faster joins (Guid is not good for that).