views:

165

answers:

3

In this answer to a recent question, I was advised to

"be wary of making every property in your domain model have public getters and setters. That can lead you to an anemic domain model."
However I then encounter the problem that an entity with private setters, like this:

public class Phrase
{
    public int PhraseId { get; private set; }
    public string PhraseText { get; private set; }
}

cannot be JSON-serialized from a View to a controller (using ASP.NET MVC). This is due to the private setter.

How would you allow serialization with private setters?

+1  A: 

You can always override the serialization or just write your own JSON deserialize method. I personally think it's not worth the effort. Just make the setter public and be done with it. What is the setter being private really buying you?

toby
Thanks for the thoughts. I agree. It might only buy some academic satisfaction...
Ole Lynge
+1  A: 

I don't know if you can override the deserialization process with MVC, but note that DataContractSerializer supports non-public accessors, and there is a JSON version: DataContractJsonSerializer - maybe worth a look?

Personally, though, I'd just accept the public setter in this case... this is a pretty common feature of .NET DTOs and .NET-based serializations. The immutable/factory pattern, while common in java, hasn't really taken as much hold in .NET; I can't say I mind overly.

Marc Gravell
Thanks for the comments. I will settle on the public setter...
Ole Lynge
+1  A: 

I was the one quoted in this question. You might notice that I never advised you to use private setters. I simply said not to make every single one of them public, if you can help it.

In your case, I'd favor making them package-private or internal, and placing the class that does serialization / saves them to a back-end / builds a DTO for your UI / whatever in the same package or assembly.

The reason not to make every private member publicly gettable and settable is a coupling question, and it is entirely practical. Your domain model needs to be coupled to domain concepts. If those concepts are embodied by getters, then use them.

Making them all public exposes you to coupling domain objects to private parts of your objects that are liable to change outside of your domain. It also encourages others to extract such information, make decisions based on that data, and set values back, which is the domain anemia you are rightly concerned about.

moffdub