I'm not well versed in domain driven design and I've recently started created a domain model for a project. I still haven't decided on an ORM (though I will likely go with NHibernate) and I am currently trying to ensure that my Value Objects should be just that.
I have a few VOs that have almost no behavior other than to encapsulate "like" terms, for instance:
public class Referral {
public Case Case { get; set; } // this is the a reference to the aggregate root
public ReferralType ReferralType { get; set; } // this is an enum
public string ReferralTypeOther { get; set; }
} // etc, etc.
This particular class has a reference to "Case" which is two levels up, so if say I were going to access a Referral I could go: case.social.referral (Case, Social and Referral are all classes, there is a single Social inside a Case and there is a single Referral inside a Social). Now that I am looking at it as I type it, I don't think I need a Case in the Referral since it will be accessible through the Social entity, correct?
Now, there is no doubt in my mind this is something that should be a VO, and the method I plan to use to persist this to the database is to either have NHibernate assign it a surrogate identifier (which I am still not too clear on, if anyone could please elaborate on that too it would help me out, since I don't know if the surrogate identifier requires that I have an Id in my VO already or if it can operate without one) and/or a protected Id property that would not be exposed outside the Referral class (for the sole purpose of persisting to the DB).
Now on to my title question: Should a VO have a collection, (in my case a List) inside it? I can only think of this as a one-to-many relationship in the database but since there is no identity it didn't seem adequate to make the class an entity. Below is the code:
public class LivingSituation {
private IList<AdultAtHome> AdultsAtHome { get; set; }
public ResidingWith CurrentlyResidingWith { get; set } // this is an enum
} // etc, etc.
This class currently doesn't have an Id and the AdultsAtHome class just has intrinsic types (string, int). So I am not sure if this should be an entity or if it can remain as a VO and I just need to configure my ORM to use a 1:m relationship for this using their own tables and a private/protected Id field so that the ORM can persist to the DB.
Also, should I go with normalized tables for each of my classes, or not? I think I would only need to use a table per class when there is a possibility of having multiple instances of the class assigned to an entity or value object and/or there is the possibility of having collections 1:m relationships with some of those objects. I have no problem with using a single table for certain value objects that have intrinsic types but with nested types I think it would be advantageous to use normalized tables. Any suggestions on this as well?
Sorry for being so verbose with the multiple questions:
1) Do I need a surrogate identifier (with say NHibernate) for my value objects?
2) If #1 is yes, then does this need to be private/protected so that my value object "remains" a value object in concept?
3) Can a value object have other value objects (in say, a List) or would that constitute an entity? (I think the answer to this is no, but I'd prefer to be sure before I proceed further.)
4) Do I need a reference to the aggregate root from a value object that is a few levels down from the aggregate root? (I don't think I do, this is likely an oversight on my part when writing the model, anyone agree?)
5) Is it OK to use normalized tables for certain things (like nested types and/or types with collections as properties which would need their own tables anyway for the 1:m relationship) while having the ORM do the mapping for the simpler value objects to the same table that belongs to my entity?
Thanks again.
Take a look at the answers to related questions here and here
1) Yes - If you're storing VOs in their own table
2) If you can use a private/protected ID property, then great. Alternatively, you might use explicit interfaces to 'hide' the ID property.
But, reading into your question, are you suggesting that developers who see an ID property will automatically assume the object is an entity? If so, they need (re)training.
3) Yes it can, but with the following restrictions:
It should be quite rare
It should only reference other VOs
Also, consider this: VOs shouldn't stick around. Would it be easy/efficient to re-create the entire VO every time it's needed? If not, make it an Entity.
4) Depends on how you want to implement your Aggregate Locking. If you want to use Ayende's solution, the answer is yes. Otherwise, you would need a mechanism to traverse the object graph back to the Aggregate Root.
5) Yes. Don't forget that DDD is Persistence Ignorant (in an ideal world!).
However...
I believe Referral should be an Entity. Imagine these conversations:
Conversation 1:
Tom: "Hey Joe! Can you give me David Jone's referral?"
Joe: "Which one?"
Tom: "Sorry, I mean Referral No.123"
Conversation 2:
Tom: "Hey Joe! Can you give me David Jone's referral?"
Joe: "Which one?"
Tom: "I don't care - just give me any"
Conversation 1 suggests that Referral is an Entity, whereas conversation 2 suggests it's a VO.
One more thing: Does Referral.ReferralType change during it's lifetime (there's another hint that it should be an Entity)? If it doesn't change, consider using polyporphism and let NH handle it.
Hope that helps!
Related
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.
In our project we use DDD as architecture (clean architecture).
Let's say I have an entity called A. A has a property called B.
Now I want a validation that when a second entity A is created, that B must be unique over all instances of A in a store.
My idea was to implement a domain service for it, using the repository. The question then is if this domain service should implement the validation itself or just provide that data for it... (to be used in the interactor/usecase for validation).
Example code (code is kept simple):
public class A
{
public A(string b)
{
B = b;
}
public string B {get; private set;}
}
Let's say I have an entity called A. A has a property called B. Now I want a validation that when a second entity A is created, that B must be unique over all instances of A in a store.
The problem you are trying to solve is sometimes known as set validation.
The easy answer: you introduce an index, that tracks the mapping of each value B to the specific entity A that is allowed to own it.
Of course, that introduces contention; you'll need to mitigate the case where two different A's are being modified at the same time. The index, and all of the A's, become part of a single consistency boundary that needs to be managed. This is pretty much what happens when we are storing our entites in a single RDBMS -- we can introduce a constraint to ensure that there are no duplicates.
You can split that single consistency boundary into separate A entities, and also individual B->A entities. But now you have the possible problem of trying to modify two different consistency boundaries at the same time, and that introduces race conditions.
A third possibility is to relax the consistency constraint -- allow conflicts to be stored, and resolve them later. See, for example, Greg Young on warehouse systems and Udi Dahan on race conditions.
The usual answer from domain-driven-design is to push back really hard on that requirement, to make sure that it is real: what's the actual cost to the business if the constraint is violated?
Think airplane seat maps: obviously only one passenger should be sitting in a seat. But that doesn't mean it's a critical failure for the seat to be assigned to more than one person, because the human operators (gate agents) have ways of mitigating these problems. See also Greg Young's talk Stop Over Engineering.
I think a domain service is the option to take, take a look at this blog(blog.sapiensworks.com/post/2017/08/23/…) where the 'username must be unique' scenario is given, resembling my issue in the initial post.
I have inherited a very sloppy project and I am tasked with explaining why its bad. I've noticed all over the code they have done comparisons like this
(IQueryable).FirstOrDefault(x => x.Facility == facility && x.Carrier == shipCode.Carrier
in the example above x.Facility is from the database and facility is from shipment.facility which is mapped as a complex object in nhibernate.
I would have expected to see .FirstOrDefault(x => x.Facility.ID == facility.ID
At first I thought comparing the whole object might cause issues if the facility record was changed in the db then the facility stored in shipment would obviously be different.
After thinking about it more I realized that shipment.facility was populated from the id so it should match even if that facility record changed.
It still feels wrong to me I see this being very buggy and hard to track down? Is there somthing specifically wrong with comparing the entire object vs an id.
Expanding my previous comments into an answer:
I think this is actually good practice when the ORM allows it. I'm not experienced with NHibernate, so for the rest of the answer I'll assume that it does in fact implement equality in a sensible way (such as comparing primary keys). You should ensure this is the case, otherwise the code would be not only bad but potentially buggy.
As an analogy, forget about SQL for the moment, imagine you were dealing with a POCO which was not part of any ORM. You want to choose between the following:
Approach 1: IEquatable
public class Facility : IEquatable<Facility>
{
public int Id {get; private set;}
//The rest of the properties
public bool Equals(Facility other)
{
return other.Id == Id;
}
}
(You'd also want to override Object.Equals, but I'll exclude that for brevity)
Approach 2: IEqualityComparer
public class Facility
{
public int Id {get; private set;}
//The rest of the properties
}
public class FacilityIdsMatchEqualityComparer : IEqualityComparer<Facility>
{
public bool Equals(Facility x, Facility y)
{
return x.Id == y.Id;
}
}
(GetHashCode also excluded for brevity).
Which of the two approaches is better? Well, I'd say it's Approach 1 by a clear margin. It adheres to two important principles that Approach 2 doesn't:
Don't repeat yourself. In the second approach, any code anywhere trying to compare facilities would have to use the FacilityIdsMatchEqualityComparer. This fact, that particular equality comparison logic needs to be used, would be sprayed all over the solution, repeated every time you want to compare them.
Single responsibility principle. Not only does every class doing the comparison need to repeat code, but that code is taking on a responsibility that doesn't belong to the class. It should be up to the Facility to express the implementation of equality, not up to every class that wants to use it to say that it's done by comparing Ids. (Yes I realise that you could just make it, say, FacilityEqualityComparer so that the calling classes remain agnostic about how the equality comparison is done, but the purpose of this is as an analogy with the code in the OP, where the exact comparison logic is hard coded into every comparison)
So, bringing it back to the actual question, this analogy very closely mirrors the situation you have here. It's not quite as simple as the Facility implementing IEquatable, but the principle is exactly the same: the ORM is taking its own responsibility for how equality checking is implemented, rather than pushing that responsibility out to code using it.
This means that if I'm writing code, say outside of the data access layer, I can say "I want to check if these two objects are equal, so I'll write object1 == object2", rather than "I want to check if these two objects are equal, and these two objects are entities, which because of the way we implement our persistence means that when I check for equality that will be converted into a SQL query, so I need to write this check as if I were writing SQL, which means I need to compare their primary keys, which either by checking attributes or maybe through my knowledge of conventions in the data access layer, I know means comparing their Id properties. So I'll write object1.Id == object2.Id".
ORMs aren't perfect, and you can't always completely abstract away the underlying SQL database, but when you can, you should!
I am not sure what you are using but normally Entity Framework should give you an error like this if you compare the objects:
Unable to create a constant value of type '...'. Only primitive types
or enumeration types are supported in this context.
Because you are sending a class needs to be converted into SQL. In any case comparing objects is not ideal for SQL code if you are trying to send a query to SQL Server.
I’ve done some Googling but I have yet to find a solution, or even a definitive answer to my problem.
The problem is simple. I want to dynamically create a table per instance of a dynamically named/created object. Each table would then contain records that are specific to the object. I am aware that this is essentially an anti-pattern but these tables could theoretically become quite large so having all of the data in one table could lead to performance issues.
A more concrete example:
I have a base class/interface ACCOUNT which contains a collection of transactions. For each company that uses my software I create a new concrete version of the class, BOBS_SUB_SHOP_ACCOUNT or SAMS_GARAGE_ACCOUNT, etc. So the identifying value for the class is the class name, not a field within the class.
I am using C# and Fluent nHibernate.
So my questions are:
Does this make sense or do I need to clarify more? (or am I trying
to do something I REALLY shouldn’t?)
Does this pattern have a name?
Does nHibernate support this?
Do you know of any documentation on
the pattern I could read?
Edit: I thought about this a bit more and I realized that I don't REALLY need dynamic objects. All I need is a way to tie objects with some identifier to a table through NHibernate. For example:
//begin - just a brain dump
public class Account
{
public virtual string AccountName { get; set; }
public virtual IList Stuff { get; set; }
}
... somewhere else in code ...
//gets mapped to a table BobsGarageAccount (or something similar)
var BobsGarage = new Account{AccountName="BobsGarage"};
//gets mapped to a table StevesSubShop(or something similar)
var StevesSubShop = new Account{AccountName="StevesSubShop"};
//end
That should suffice for what i need, assuming NHibernate would allow it. I am trying to avoid a situation where one giant table would have the heck beat out of it if high volume occurred on the account tables. If all accounts were in one table... it could be ugly.
Thank you in advance.
Rather than creating a class on the fly, I would recommend a dynamic object. If you implement the right interfaces (one example is here, and in any case you can get there by inheriting from DynamicObject), you can write
dynamic bobsSubShopAccount = new DynamicAccount("BOBS_SUB_SHOP_ACCOUNT");
Console.WriteLine("Balance = {0}", bobsSubShopAccount.Balance);
in your client code. If you use the DLR to implement DynamicAccount, all these calls get intercepted at runtime and passed to your class at runtime. So, you could have the method
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
if (DatabaseConnection.TryGetField(binder.Name, out result))
return true;
// Log the database failure here
result = null;
return false; // The attempt to get the member fails at runtime
}
to read the data from the database using the name of the member requested by client code.
I haven't used NHibernate, so I can't comment with any authority on how NHibernate will play with dynamic objects.
Those classes seem awfully smelly to me, and attempt to solve what amounts to be an actual storage layer issue, not a domain issue. Sharding is the term that you are looking for, essentially.
If you are truly worried about performance of the db, and your loads will be so large, perhaps you might look at partitioning the table instead? Your domain objects could easily handle creating the partition key, and you don't have to do crazy voodoo with NHibernate. This will also more easily permit you to not do nutty domain level things in case you change your persistence mechanisms later. You can create collection filters in your maps, or map readonly objects to a view. The latter option would be a bit smelly in the domain though.
If you absolutely insist on doing some voodoo you might want to look at NHibernate.Shards, it was intended for easy database sharding. I can't say what the current dev state and compatibility is, but it's an option.
I'm reading about the Entity Framework 4.0 and I was wondering why should I create a complex type and not a new Entity (Table) and a relation between them?
The perfect example is an address. Using a complex type for an address is much easier to deal with than a new entity. With complex types you do not have to deal with the Primary Key. Think about accessing an address how many common types of entities would have an address (Business Units, People, Places). Imagine populating many peoples addresses and needing to set a key for each one. With complex types you simply access the internal properties of they type and you're done. Here is an MSDN link of an example. http://msdn.microsoft.com/en-us/library/bb738613.aspx
This question has been here a while already, but I'm going to add an answer anyway in the hopes that the next poor sob that comes along knows what he's in for.
Complex types do not support lazy loading, at least not in EF 4.3. Let's take the address situation as an example. You have a Person table with 15 columns, 5 of which contain address information for certain individuals. It has 50k records. You create entity Person for the table with a complex type Address.
If you need a list of names of all individuals in your database you would do
var records = context.Persons;
which also includes addresses, pumping 5*50k values into your list for no reason and with noticeable delay. You could opt to only load the values you need in an anonymous type with
var records = from p in context.Persons
select new {
LastName = p.LastName,
FirstName = p.FirstName,
}
which works well for this case, but if you needed a more comprehensive list with, say, 8 non-address columns you would either need to add each one in the anonymous type or just go with the first case and go back to loading useless address data.
Here's the thing about anonymous types: While they are very useful within a single method, they force you to use dynamic variables elsewhere in your class or class children, which negate some of Visual Studio's refactoring facilities and leave you open to run-time errors. Ideally you want to circulate entities among your methods, so those entities should carry as little baggage as possible. This is why lazy loading is so important.
When it comes to the above example, the address information should really be in a table of its own with a full blown entity covering it. As a side benefit, if your client asks for a second address for a person, you can add it to your model by simply adding an extra Address reference in Person.
If unlike the above example you actually need the address data in almost every query you make and really want to have those fields in the Person table, then simply add them to the Person entity. You won't have the neat Address prefix any more, but it's not exactly something to lose sleep over.
But wait, there's more!
Complex types are a special case, a bump on the smooth landscape of plain EF entities. The ones in your project may not be eligible to inherit from your entity base class, making it impossible to put them through methods dealing with your entities in general.
Assume that you have an entity base class named EntityModel which defines a property ID. This is the key for all your entity objects, so you can now create
class EntityModelComparer<T> : IEqualityComparer<T> where T : EntityModel
which you then can use with Distinct() to filter duplicates from any IQueryable of type T where T is an entity class. A complex type can't inherit from EntityModel because it doesn't have an ID property, but that's fine because you wouldn't be using distinct on it anyway.
Further down the line you come across a situation where you need some way to go through any entity and perform an operation. Maybe you want to dynamically list the properties of an entity on the UI and let the user perform queries on them. So you build a class that you can instantiate for a particular type and have it take care of the whole thing:
public class GenericModelFilter<T> : where T : EntityModel
Oh wait, your complex type is not of type EntityModel. Now you have to complicate your entity inheritance tree to accommodate complex types or get rid of the EntityModel contract and reduce visibility.
Moving along, you add a method to your class that based on user selections can create an expression that you can use with linq to filter any entity class
Expression<Func<T, bool>> GetPredicate() { ... }
so now you can do something like this:
personFilter = new GenericModelFilter<Person>();
companyFilter = new GenericModelFilter<Company>();
addressFilter = new GenericModelFilter<Address>(); //Complex type for Person
...
var query = from p in context.Persons.Where(personFilter.GetPredicate())
join c in context.Companies.Where(companyFilter.GetPredicate()) on p.CompanyID = c.ID
select p;
This works the same for all entity objects... except Address with its special needs. You can't do a join for it like you did with Company. You can navigate to it from Person, but how do you apply that Expression on it and still end up with Person at the end? Now you have to take moment and figure out this special case for a simple system that works easily everywhere else.
This pattern repeats itself throughout the lifetime of a project. Do I speak from experience? I wish I didn't. Complex types keep stopping your progress, like a misbehaved student at the back of the class, without adding anything of essence. Do yourself a favor and opt for actual entity objects instead.
Based on Domain Driven Design Concepts, Aggregate root could have one or more internal objects as its parts. In this case, Internal objects - inside the boundary of Aggregate Root - does not have any KEY. The parent key will be applied to them or somehow like this. Your answer returns to the benefit of keeping all Parts inside Aggregate root that makes your model more robust and much simpler.