开发者

C# DDD Populate Immutable Objects

I have a 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 assembly. In turn, this CustomerRepository class should populate and return a Customer object using a remote web-serivce.

My Customer class contains no setter properties and it contains a private constructor. The reason - I dont want the UI developer to get the wrong idea - He should not be able to create or change a Customer object.

My question: How do I get my CustomerRepository to populate my Customer object. Reflection? 开发者_Python百科Or should I sacrifice my design and enable a public constructor for constructing the customer object?


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 make it clear enough that the customer is immutable.

If you really don't want a public constructor, consider whether you really need separate domain and persistence assemblies: there are good reasons to split related code into two assemblies, but it shouldn't be the default position and shouldn't replace namespaces as the primary way of organizing code (Patrick Smacchia has written a few great articles explaining why).

If you combine them into a single assembly, you can just make the constructor internal and be done with it. (As another respondent mentioned, InternalsVisibleTo is a viable alternative - but it's really just a hack: your classes and design goals are telling you these should be in a single assembly.)


You might want to declare an internal constructor, with your three properties as parameters. If your CustomerRepository does not live in the same assembly as your Customer class, then you can make your internals visible by 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 lots of objects, because doing so will be orders of magnitude slower than direct calls to constructors. If you really have to go that route, I'd recommend adding a static factory method which you can call through reflection in order 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 then on, you'll have a fast and efficient way of creating your Customers.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜