Automapper and immutability

2019-03-27 06:52发布

问题:

Is it possible to use AutoMapper with Immutable types?

For example my Domain type is immutable and I want to map my view type to this.

I believe it is not but just want this confirmed.

Also as it is best practice to have your domain types immutable, what is the best practice when mapping your view types to domain types?

回答1:

I typically do the mapping from view types to domain types by hand, as I'll typically be working through a more complex interface, using methods and so on. If you use AutoMapper to go from view to domain, you're now locked in to an anemic domain model, whether you've intentionally decided to or not.



回答2:

AutoMapper relies on property setters to do its work, so if you have read-only properties, AutoMapper won't be of much use.

You could override the mapping behaviour and, for example, configure it to invoke a specific constructor, but that basically defeats the purpose of AutoMapper because then you are doing the mapping manually, and you've only succeeded in adding a clumsy extra step in the process.

It doesn't make a lot of sense to me that your domain model is immutable. How do you update it? Is the entire application read-only? And if so, why would you ever need to map to your domain model as opposed to from? An immutable domain model sounds... pretty useless.

P.S. I'm assuming that you mean this AutoMapper and not the auto-mapping feature in Fluent NHibernate or even some other totally different thing. If that's wrong then you should be more specific and add tags for your platform/language.



回答3:

Suppose that you really did want an immutable property on your Domain type, say Id. Your domain type might look something like this:

public class DomainType
{
    public DomainType(int id)
    {
        Id = id;
    }

    public int Id { get; }
    // other mutable properties
    // ...
}

Then you can use ConstructUsing using a public constructor of your choice, such as:

CreateMap<ViewType, DomainType>()
    .ConstructUsing(vt => new DomainType(vt.Id));

Then map all the mutable properties in the normal way