Add caching for DontDirtyAttribute checking.

Reflection is way too slow to check is like that every time after all.
Implemented a simple cache mechanism to do it only once for a property.
Optimise OnPropertyChanged by keeping overhead low for non-shared.

Automatic validation, dirty marking and MessageBus broadcast on
OnPropertyChanged only happens if the model IsShared now.

This change shaved off around 50% of the time spent in the method in
overall.