I have a set of entities, for now represented by very simple classes (further simplified for this example):

public class Item
{
    public string Name { get; private set; }
    public double MainValue { get; private set; }  //should be exposed for editing in GUI
    public double Value { get; private set; }  //should be exposed for editing in GUI
}

public class Record
{
    public Item Item { get; private set; }
    public double Quantity { get; private set; } //should be exposed for editing in GUI
    public double MainValue { get { return Item.MainValue*Quantity; } }
    public double Value { get { return Item.Value*Quantity; } }
}

public class DayAccount
{
    public DateTime Date { get; private set; }
    public IEnumerable<Record> Records { get; private set; }
    public double MainValueGoal { get; private set; }   //should be exposed for editing in GUI
    public double MainValueTotal { get { return Records.Sum(r => r.MainValue); } }
    public double ValueTotal { get { return Records.Sum(r => r.Value); } }

    public void Add(Record record) {}
    public void Remove(Record record) {}
}

There is going to be a repository class for accessing, adding and persisting DayAccount entities, but that’s pretty much it. The end user should be able to modify some properties of these entities through the GUI if he needs to edit them, but all other operations on them will be pure data analysis and read-only. The entities will also be persisted, read and updated by an ORM, and will serve as models in the MVVM pattern.

What bothers me is that these entities will be passed around heavily, and I would like to protect them from unintentional modifications of their properties in code.

First of all – is implementing any type of protection worth it? Unintentional modifications will only happen in case of a programmer error/poor usage of the class. Maybe the entities should be left fully mutable, and the code well-documented and deemed safe as long as it is thoroughly covered by tests and passes them?

For educational purposes, suppose the protection from unintended changes is mandatory. How can I enforce it? Making the objects completely immutable and cloning them might pose difficulties when working with the ORM. Providing a simple mutable/immutable switch is misleading in a multithread context. Introducing immutable interfaces that expose a mutable object like in this answer doesn’t enforce immutability, it just hides the objects – it is more explicit for a user of this code, but doesn’t fully protect from a programmer error.

I’m using C# 5 and .NET Framework 4.5.

UPDATE

Okay, I have realized how little I know about domain driven design and its concepts. Anyway, based on the two answers in this thread I’ve came up with the following design:

  • There will be a repository class that hides the ORM and persistence logic. The ORM works with DTOs (all setters public, no validation, default constructor). The users of the repository can’t see the DTOs but are able to query immutable domain objects that the repository creates based on these DTOs.
  • For adding/editing entities, a viewmodel is created and its properties populated with values from the domain object. The viewmodel is fully mutable and has all the validation logic. On save, a new domain object is created with the values from the viewmodel, and then saved or updated through the repository.

For me, this poses two new questions. The immutable domain object represents a valid entity, thus all its values should be validated in the constructor. The viewmodel, on the other hand, can hold incorrect values, which are then validated (for example, in the IDataErrorInfo implementation). How do I avoid duplicating the validation logic between the view model and the domain object?

Second question – to store/update a domain object through the repository, I need to track the Id value from the DTO created by the ORM and set it in the domain object. What bothers me is that this is a strictly persistence detail and has no relevance in the business logic. Is it okay that this persistence detail seeps into the domain?

How reasonable is this design? Am I even thinking in the right direction?

I would recommend mapping your DTOs to a domain object and make that domain object immutable

Just give it private setters and create it through a factory, instead of passing around the DTO all over.

Making it immutable is definitely not a bad idea if you think it should be immutable, documenting still has a risk that a new developer will enter the arena and make some initial mistakes. This is not the end of the world but you want to decrease software entropy as much as possible.

However, I would not recommend making your DTO immutable because you shouldn’t have a need for it most of the time. It is a dumb, simple object that carries data, but domain object, on the other hand, can be immutable because it reflects real life requirements of the business.

2

The entities will also be persisted, read and updated by an ORM, and will serve as models in the MVVM pattern.

Why?

I mean, you basically came out and said that you’d like your entity (as used by the business logic and used by the ORM) to be immutable, but that you’d like your model (as used by the UI) to be mutable (at least for the add/edit screen).

So decouple those two things, like they should’ve been in the first place.

3

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật