On this part of this series, we start looking at the DynamicDtoDecorator class. We begin by seeing how it takes in the object that it decorates and how it figures out what the public instance properties in the decorated object are, and how to access them. We’ll be seeing how we use the PropertyAccessor class created in the previous installment of this series.
Our DynamicDtoDecorator! We start like this:
public class DynamicDtoDecorator : DynamicObject, INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged = (sender, args) => { }; void RaisePropertyChanged(string propertyName) { PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); } }
The class inherits from DynamicObject so we can get some dynamic support for free. It also implements INotifyPropertyChanged. “But aren’t we trying to get rid of INotifyPropertyChanged?”. Yes, we’re trying to get rid of it in our ViewModels, but we still need it somewhere for WPF binding to work.
Next, we have a private field to store the DTO (Data Transfer Object) that the class decorates. The DTO is passed into the class constructor
readonly object _dto; public DynamicDtoDecorator(object dto) { _dto = dto; RegisterProperties(); }
Notice that the constructor calls out to a RegisterProperties method. Let’s see what that method looks like:
protected void RegisterProperties() { _dto.GetType() .GetProperties(BindingFlags.Public | BindingFlags.Instance) .ToList() .ForEach(prop => { object[] notIndexedProperty = null; Func valueGetter = () => prop.GetValue(dto, notIndexedProperty); Action valueSetter = newValue => prop.SetValue(dto, newValue, notIndexedProperty); Register(prop.Name, valueGetter, valueSetter); }); }
The method looks for any public instance property on the DTO type, creates getter and setter delegates, and register them with in the decorator. If you’ve been following my series on this topic, you’ll remember my explanation on a PropertyAccessor class I created in the previous installment, so you can already think how those getter/setter delegates are going to be used, right? Well, alright, I forget things all the time, too, so let’s see what that Register method looks like:
public void Register(string propertyName, Func valueGetter, Action valueSetter) { var fullPropertyName = propertyName; if (_members.ContainsKey(fullPropertyName)) return; dynamic initialValue = valueGetter.Invoke(); var propertyValue = new PropertyAccessor(propertyName, valueGetter, valueSetter, initialValue); _members.Add(fullPropertyName, propertyValue); }
Nothing special going on there. The _members field is defined in the class like this:
readonly Dictionary<string, PropertyAccessor> _members = new Dictionary<string, PropertyAccessor>();
Just a pretty Dictionary, that’s all.
Right now, our decorator knows what it needs to access on the decorated object, and how to access it. In the next part we explorer how this is going to be exposed to the outside world. Stay tuned!