How to have private constructors and private setters when using Entity Framework Core Database first

Having private constructors and private setters is one of the primary ways we can enforce encapsulation in our domain model.

Entity Framework Core can work fine with both private constructors and private setters. Developers using the code first approach can just set the access modifiers on their constructors and properties as they wish.

BUT…

To achieve something similar with the DB first workflow we need to customise the code that EF generates during the scaffolding process.

Thankfully this is easily done using the EF Core Power Tools Visual Studio extension. This extension uses the Scaffolding.Handlebars library to support the customization of code which is generated during the scaffolding process. You don’t need the extension to use the library but it’s a bit easier and EF Core Power Tools is a great extension anyway so I’ll use it in the post.

Customising Entity Framework scaffolded models

The steps are…

Install the extension via the Extensions -> Manage Extensions window.

Right click on the relevant project and select EF Core Power Tools -> Reverse Engineer and first select which tables you want to scaffold and then on the subsequent screen check the option for customizing the code…

Customise EF Code with EF Core Power Tools

After running the scaffolding you should see entities generated AND a CodeTemplates folder which contains all the handlebar template files for customizing entities and the DbContext…

Code templates folder

The two files you need to edit are highlighted above.

Your edits will look similar to below…

Private constructor

Extending Entity Framework generated models with partial classes

After changing the above files and scaffolding again all your entities should now have private constructors and private property setters. To add public constructors and public methods to your entities simply create partial classes for each entity.

Always use partial classes to extend your EF generated models. Never edit the generated models directly as you will lose your customisations each time you re-scaffold.

For example here’s a public constructor for creating an Address instance…

while here’s a public method which will allow us to update the properties of an address instance..

Now we can see that the only way to create an address is via the non default constructor. This means we can ensure that an invalid object is never created.

Create an address

Similarly when we want to update an address we cannot set properties individually as all the setters are private… we must go through the one centralised UpdateAddress method

Update an address

Summary

You’ll always get better DDD support with the Entity Framework code first workflow. For those of us who prefer the DB first approach combining the customisation of EF generated code and partial classes is a nice technique to move a little closer to a DDD based app.

Leave a Reply

Your email address will not be published. Required fields are marked *