I have been increasingly adopting DDD / Onion Architecture in my current project. One of the many things I am still unclear about is how much encapsulation should there be. Easier explained with a concrete example.
Example
namespace MyProject.Model
{
public class ComplexEntity
{
private int _id;
public int Id { get {return _id;} }
public ValueObjectA ValueA {get; set;}
public bool IsBool {get; set;}
public ComplexEntity(ValueObjectA a, bool isBool)
{
// Do some validation first
ValueA = a;
ValueB = b;
IsBool = isBool;
}
}
public class ValueObjectA
{
public bool IsBoolA {get; private set;}
public bool IsBoolB {get; private set;}
public ValueObjectA(bool a, bool b)
{
IsBoolA = a;
IsBoolB = b;
}
}
public Interface IComplextEntityFactory
{
// Option 1
ComplexEntity Create(
ValueObjectA a,
bool IsBool);
// Option 2
ComplexEntity Create(
bool valueABool a,
bool valueBBool b,
bool isBool);
}
}
Question
For the factory of an entity, do you,
- Expect the caller to construct the value objects for you and use it to initialize the ComplexEntity?
- Have essentially CLR basic types being passed to the factory and you construct every ValueObject that makes up the Entity?
I am leaning towards option 2 but I can't seem to find supporting literature for it.
Edit 1
To be honest I am still no clearer. What about aggregate roots?
When my entity refers to other entities, e.g. below.
- Should I have an
IComplexEntityFactory
,ILessComplexEntityFactory
? Or just anIComplexEntityAggregateFactory
that creates the LessComplexEntity and instantiates ComplexEntity ? - In the case of the AggregateFactory solution, what do I do if the LessComplexEntity attribtues that have been passed to the factory correspond to an existing LessComplexEntity? Do I retrieve and reuse it from a Repository? Or do I return an error to the caller?
What would the method signature be for the AggregateFactory? Would it be
(ValueObject a, ValueObject b)
, or(ValueObject value, LessCompelxEntity entity)
public class ComplexEntity { private readonly int _id; public int Id { get { return _id;} }
public ValueObject Value {get; set;} public LessComplexEntity Entity {get; set;} public ComplexEntity(int id, ValueObject value, LessComplexEntity entity) { }
}
public class LessComplexEntity { private readonly int _id; public int Id { get {return _id;} } public ValueObject Value {get; set;} public LessComplexEntity(int id, ValuObject value) { } }