el;In Part 1, I mentioned I wanted to decorate a ViewModel with “notify property changed” behavior, so I could keep my ViewModel as clean as possible. In this part I’ll go over how the properties on the decorated object are going to be accessed.
Say we have the following code:
[code language=”plain”]dynamic viewModel = new DtoDecorator(new InvoiceItemViewModel());
viewModel.ProductName = “My great product”;
Console.WriteLine(viewModel.ProductName);[/code]
A “non-dynamic” implementation of the decorator could look somewhat like this (disregard the implementation of INotifyPropertyChanged for now):
[code language=”plain”]public class DtoDecorator
{
InvoiceItemViewModel _decoratedViewModel;
public DtoDecorator(InvoiceItemViewModel viewModel)
{
_decoratedViewModel = viewModel;
}
public string ProductName
{
get
{
return _decoratedViewModel.ProductName;
}
set
{
_decoratedViewModel.ProductName = value;
}
}
}[/code]
The important aspect in the code above is that the decorator has to be able to access properties on the decorated object. In order to come up with a generic way to do that, I’ve created a PropertyAccessor class, designed to get/set value on a property.
The PropertyAccessor class uses a Func delegate to do the “get” and an Action delegate to do the “set”, like so:
[code language=”plain”]var viewModel = new InvoiceItemViewModel { ProductName = “Some value” };
var getter = new Func(() => viewModel.ProductName);
var setter = new Action(value => viewModel.ProductName = value.ToString());
_propertyAccessor = new PropertyAccessor(“ProductName”, getter, setter, initialValue);[/code]
With that in place, we can get or set that property like so:
[code language=”plain”]_propertyAccessor.Set(“New value”);
var currentValue = _propertyAccessor.Get();[/code]
This is what the PropertyAccessor class looks like:
[code language=”plain”]public class PropertyAccessor
{
readonly Func _getter;
readonly Action _setter;
public PropertyAccessor(string propertyName,
Func getter,
Action setter,
dynamic initialValue)
{
PropertyName = propertyName;
_getter = getter;
_setter = setter;
InitialValue = initialValue;
CurrentValue = initialValue;
}
public string PropertyName { get; }
public dynamic InitialValue { get; }
public dynamic CurrentValue { get; private set; }
public bool Changed => InitialValue != CurrentValue;
public dynamic Get()
{
return _getter.Invoke();
}
public void Set(dynamic value)
{
_setter.Invoke(value);
CurrentValue = value;
}
}[/code]Notice we also keep track of initial and current values so we can do some basic change tracking, which comes in handy.
Now that we have a generic way to get/set value on properties of an object, the next step will be to look at that decorator class. Coming up next!




Leave a Reply