Event trigger on property change - c#

I am trying to write an analysis tool that compares and tracks data over time in your application.
My goal currently is to find a way to send a trigger to a manager, once the value of a tracked property changes.
This process of setting up tracked properties should be as simple as possible, in an ideal world without the need of changes on the actual property code-wise, like the INotifyPropertyChanged interface. Any property with a valid getter&setter should be trackable.
My idea was to use Reflection to hook into the setter method of the property, and add a callback there once the setter is called.
Is there a better way to go about this? Or can reflection manage this, and if yes, how?

If triggers should be sent as soon as possible on every change, the only option is to add wrappers around properties (one way or the other). AOP frameworks can significantly simplify this and help to avoid boilerplate code (e.g. INotifyPropertyChanged "pattern"). There are a few of them each with its pros and cons, for example:
PostSharp
AspectInjector (an example of what may be helpful for your needs
https://github.com/pamidur/aspect-injector/tree/master/samples/NotifyPropertyChanged)

Related

Does there exist any version of `INotifyPropertyChanged` for multiple changes?

I read about Observer pattern in the GoF book.
.Net Framework contains the INotifyPropertyChanged interface. Has .Net Framework the similar interface but for notifying about changing of the set of properties instead of notifying about each property changed (for increase in productivity)?
I created such interface INotifySubjectChanged for my application (its event argument contains the set of changed properties) but maybe .Net Framework already has it and I invented a bicycle.
I published my simple code source on Bitbucket.org here. It maybe more clear what I want to do.
MSDN states that leaving the property name blank implies that all of the properties on the object have changed.
https://msdn.microsoft.com/en-us/library/system.componentmodel.inotifypropertychanged.propertychanged(v=vs.110).aspx
The PropertyChanged event can indicate all properties on the object have changed by using either null or String.Empty as the property name in the PropertyChangedEventArgs.
Which is probably as close as you could get to what you are asking for from the .NET framework. Note that using this incorrectly and calling it when a smaller number of properties have changed might actually reduce performance in certain situations.
For record if the object is a collection (which you said it is not) you could leverage INotifyCollectionChanged.
If you are concerned about performance and efficiency, I'd first make sure that you actually are having performance issues and that the notification of changes is causing those performance issues.
If you are not concerned about your implementation working with WPF data binding and it is relatively clear as to its behavior, then I don't see anything wrong with the custom interface and event.

Watch object state

I was working with angular-js and came across interesting feature that can watch object for changes.
I wonder if there is something similar in c#. I thought to create some watcher that will accept object to be watched, and may be check the hash code of the object periodically to find out if object changed, then rise an event. But that seems a bit inefficient.
Any ideas?
Thanks
That wouldn't work anyway, firstly because there is no requirement for a property change to affect the hash code, and secondly, even if it did affect the hash code, it would be possible for the new hash code to be equal to the old hash code.
What AngularJS does is keep track of the last-known values, and then re-load all of the values, comparing them to the prior ones. If they're no longer equal, there has been a change.
You could do the same in C# if you want to.
But a way that's more common in C# is for the object being watched to implement the INotifyPropertyChanged interface, and raise the PropertyChanged event on each property change. This gives the object the ability to notify any interested watchers that properties have changed, without requiring the watcher to do any polling.
In both JavaScript and C#, objects aren't observable per se.
Actually, Angular turns objects into observable objects under the hoods, and since JavaScript is a dynamically-typed language this conversion or wrapping can be done in a painless way.
Since C# is a strongly-typed language, you can't observe objects if they don't implement an interface or something that can expose an event to subscribe to changes. Usually observable objects should implement INotifyPropertyChanged interface.
Other way of implementing this is using a framework like Castle DynamicProxy to create proxies of your classes and intercept both method calls and property gets and sets.

Use Castle DynamicProxy to rollback property changes

I've found many examples of DynamicProxy used to perform additional work when property changes in the object, but how do I not only set the property value in the interceptor (by calling Proceed()), but also roll it back, if something went wrong during interception itself?
Usecase here is this: I use settings objects to provide setting values to some parts of the system, so they won't have to work with the configuration backend.
These objects are also INotifyPropertyChanged, so if anyone changes the setting at runtime, the component which has the object gets notified about the change and can perform reconfiguration on the fly.
So what I need to do is roll back the change of the property if PropertyChanged event handler has thrown an exception (the change led to misconfiguration or was invalid).
I wonder how it can be done.
I've ended up using both INotifyPropertyChanging (and extended this interface a bit) and INotifyPropertyChanged. Simply because the validation should be performed before the actual setting, because
order of events is not determined, and so the actual consumer of the setting can get the notification before it has been even validated, when you using only INPChanged
and overall the validation and consuming are different and should have different events: one before the setting took place (to prevent it from happening) and one after - when the actual value of the property is already updated (for the code to work as expected).
When I look at this now, the original design (which the question is about) seems bad to me.

Dynamically overriding a method -or- observing when a method is called at runtime?

I'm primarily an Objective-C/Cocoa developer, but I'm trying to implement the Observer pattern in C#.NET, specifically mimicking the NSKeyValueObserving protocols and methodology.
I've gotten as far as mimicking NSKVO with manual support, as described in Apple's KVO Programming Guide (see http://tinyurl.com/nugolr). Since I'm writing the setValue:forKey: methods myself, I can implement auto KVO notification through there.
However, I'd like to somehow implement auto KVO on all properties by dynamically overriding them at runtime. For example, replacing Button.Title.set with:
set {
this.willChangeValueForKey("title");
title = value;
this.didChangeValueForKey("title");
}
So, this is my question:
How do I dynamically override a method or property at runtime in C#? I've gotten as far as getting and invoking methods and properties by name using Reflection.MethodInfo. Alternatively, can I observe the runtime and find out when a method is about to be/has been called?
Dynamic metaprogramming and aspect oriented programming are not yet strongly supported in C#. What you can do, is look at a free tool called PostSharp - it allows supports weaving aspects into your code around properties and method calls quite easily.
You can implement the INotifyPropertyChanged interface (without postsharp) and it can be used in certain contexts to notify observers that a value of a property has changed. However, it still requires that each property actually broadcast the change notification - which generally requires it to be specifically coded to support that. Injecting change notification to existing code (without actually changing the source) is not an easy thing to do in straight-up C#. PostSharp (other other AOP/dynamic proxy libraries) make this sort of thing dramatically easier.
I'm not sure if you need to go down this road or not. But if you want to implement overrides of a method (i.e. generating new code for the method?) then it is possible with Emit. I would explore any other suggestions first before diving into those deep waters.
You're looking for INotifyPropertyChanged. You can dynamically implement that using PostSharp, Castle DynamicProxy or probably any other proxying library.
This does not solves the problem of having to add the tracking code dynamically, but can be interesting to read: Trackable Properties with Weak Events
With this stuff you are able to track changes to specific properties and it makes easier to implement INotifyPropertyChanged (i.e. track changes to all properties).
After doing extensive research on this subject, it appears that I can't do exactly what I'd like to do with .NET in its current state.
PostSharp's method is done at compile time, meaning I can't dynamically insert my own implementations to methods.
Reflection.Emit allows me to do this dynamically, but it generates a new instance of the created subclass - I need to do this so it works with the original instance.
INotifyPropertyChanging and INotifyPropertyChanged would be perfect if any of the existing .NET classes actually used them.
... so, at the moment I'm a bit stuck. I've put a more detailed piece on what I'm doing and how I'm trying to achieve in a post on my blog. Here's hoping .NET 4.0's dynamic dispatch will help!

AOP Dirty Tracking

In the past I have used a few different methods for doing dirty checking on my entities. I have been entertaining the idea of using AOP to accomplish this on a new a project. This would require me to add an attribute on every proptery in my classes where I want to invoke the dirty flag logic when the property is set. If I have to add an extra line of code to each property for the attribture, what is the benefit over just calling a SetDirty() method in the setters. I guess I am asking what would be the advantage, if any, of using the AOP approach?
I'd say that not only is there not any advantage in this case: there's a bit of a disadvantage. You're using the same number of lines of code whether you call dirty() or you use AOP, but just calling dirty() is more simple and clear, as far as intent goes.
AOP, honestly, is a bit oversold, I think. It adds another level of indirection, in terms of reading the code, that often it doesn't pay back.
The key thing to think about here is, does it help the next guy reading this (which may be you a few months down the road) understand more quickly and clearly what I'm trying to do. If you have trouble figuring out what's better about the less straightforward approach, you probably shouldn't be using it. (And I say this as a Haskell programmer, which means I'm far from adverse to non-straightforward approaches myself.)
The advantage is that should you decide to change the implementation of how to invoke the dirty flag logic, you'll only need to make one change (in the AOP method's body), not N changes (replacing all your SetDirty calls with something else).
I don't see any benefit if you have to decorate your entities with an attribute. Espeically if all your doing is calling a single method. If the logic was more complex then I could make an argument for using AOP.
If let's say each time you modify a property you wanted to track that change as a version, this might be more complex behavior that could be injected, then having this abstracted out of the property could be beneficul. At the same point you would probally want to version changing several properties at once so I come back to there not being much value.
The use of AOP is for cross cutting concerns. This means that you want to have a feature such as logging, security, ect but the business logic really does not belong in your class. This could be for the Dirty flag logic as the Domain object should not care that it has been changed. That is up to your DirtyLogicUtility or what ever name it has.
For example you want to log every time a method gets called for every you could place this in every function, but later on you want to have logic so that it is logged on every other call.
AOP keeps your classes clean doing what they are supposed to do while leaving the other pieces alone.
Some AOP implementations, specifically PostSharp, allow you to apply the attribute at an Assembly level with wildcards as to which classes it applies to.
Why do you want the dirty check to be the responsibility of the entities? You can manage this somewhere else. The pattern is called Unit of work

Categories