C # DDD Filling Immutable Objects

I have an immutable Customer class in my domain assembly. It contains the following GET properties: id, firstname, and lastname. I have a CustomerRepository class in my persistence build. In turn, this CustomerRepository class must populate and return a Customer object using a remote web service.

The My Customer class does not contain setter properties and contains a private constructor. The reason is I do not want the user interface designer to make a mistake. It must not create or modify a Customer object.

My question is: how can I get my CustomerRepository to populate the Customer object. Reflection? Or should I sacrifice my design and enable a public constructor to create a client object?

+4
source share
2 answers

I sympathize with the desire to reduce the surface of the API and not mislead callers, but I still recommend adding a public constructor. The fact that there are no setters and no public SaveCustomer method should clearly indicate that the client is unchanged.

If you really don’t want a public constructor, think about whether you really need separate domain and persistence assemblies: there are good reasons to split the linked code into two assemblies, but it should not be the default and should not replace namespaces as the main way to organize the code (Patrick Smacchia has written some great articles explaining why ).

If you combine them into one assembly, you can just make the constructor internal and make with it. (As another respondent noted, InternalsVisibleTo is a viable alternative, but it is really just a hack: your design classes and design goals tell you that they should be in the same assembly.)

+3
source

You might want to declare an internal constructor with your three parameters. If your CustomerRepository does not live in the same assembly as your Customer class, you can make your internal visible using the following attribute:

 [assembly: InternalsVisibleTo ("CustomerAssembly, PublicKey=...")] 

in the Customer assembly.

Edit: By the way, I would not recommend using reflection if you need to create many objects, because it will be an order of magnitude slower than direct calls to designers. If you really need to go this route, I would recommend adding a static factory method that you can call through reflection to get an efficient allocator.

For instance:

 class Customer { private Customer(...) { ... } private static ICustomerFactory GetCustomerFactory() { return new CustomerFactory(); } private class CustomerFactory : ICustomerFactory { Customer CreateCustomer(...) { return new Customer(...); } } } public interface ICustomerFactory { Customer CreateCustomer(...); } 

Use reflection to call Customer.GetCustomerFactory , and from now on you will have a quick and efficient way to create Customer s.

+2
source

Source: https://habr.com/ru/post/1310862/


All Articles