Why would I do that?
I recently started a new personal project following the DDD approach.
If you strictly follow the DDD rules, you need to create a new class for each property.
And initializing those classes can quickly become a burden.
Example:
var person = new Person(
new PersonId(1),
new PersonFirstName("Clément"),
new PersonLastName("Kiritchouk"),
new PersonBirthYear(1994))
There's a way to save a few keystrokes, increase readability and make chaining easier.
Static constructors obviously
Disclaimer: This is my way of doing this, feel free to adapt or improvre
First, Create a static partial Constructors class like this:
// Constructors.cs
public static partial class Constructors
{
}
I use this class for System classes (DateTime, List, ...)
I'll add some interesting ones later on...
Then create another static partial Constructors class where I put all my Person constructors.
// Constructors.Person.cs
public static partial class Constructors
{
public static PersonId PersonId(int id) => new PersonId(id);
public static PersonFirstName PersonFirstName(string firstName) => new PersonFirstName(firstName);
public static PersonLastName PersonLastName(string lastName) => new PersonLastName(lastName);
public static PersonBirthYear PersonBirthYear(int year) => new PersonBirthYear(year);
public static Person Person(PersonId id, PersonFirstName firstName, PersonLastName lastName, PersonBirthYear year)
=> new Person(PersonId(id), PersonFirstName(firstName), PersonLastName(lastName), PersonBirthYear(year));
}
And Done!
How to use it
It's refactoring time. Now we can initialize a Person class like this.
Actually, it's easy... Just drop the new
keyword.
Don't forget the static using!
using static MyAwesomeProject.Constructors
var person = Person(
PersonId(1),
PersonFirstName("Clément"),
PersonLastName("Kiritchouk"),
PersonBirthYear(1994))
Bonus
Ok, maybe you're not convinced yet.
Let's create a list of persons
var persons = new List<Person>{
person1,
person2,
person3
};
Why not create a constructor for initializing List?
Update your Constructors.cs file like this:
// Constructors.cs
public static partial class Constructors
{
public static List<T> List<T>(params T[] items) => new List<T>(items);
}
Now you can do
var persons = List(person1,person2,person3);
You don't have to specify the type anymore because the type system infers it.
Cons
Well, there are some cons using this technique.
- You have to create a constructor for every type while
new
is built-in. - It's unusual, other developers might be confused looking at your code.
Anyway, I like it and I had to share it with you. Please tell me what are your thoughts on this. 😏
Top comments (5)
Might be better to have implicit conversion from string/int to the property type, but not from the property type back.
Maybe I didnt get it right but if you do that you won't get type checking anymore.
Because then a string can convert to a Name or a FirstName.
Yes it can, but you can just as easily pass the wrong string value to your constructor.
It's not string to FirstName you are trying to prevent, it is FirstName to LastName.
Why do we need to get rid of
new
keyword ? The approach show here seems to be a syntactic sugar. Do this approach increase readability of code ?Why do we need to get rid of
new
keyword ?You don't need to. And you should not if you don't see any benefit.
The approach show here seems to be a syntactic sugar.
That's 100% syntactic sugar.
Do this approach increase readability of code ?
Readability is subjective.
You might be confused the first time you see this.
But then, it feels like the code is less noisy and cluttered with useless keyword and types