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.
Related
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)
Using Protobuf-net, I want to know what properties of an object have been updated at the end of a merge operation so that I can notify interested code to update other components that may relate to those updated properties.
I noticed that there are a few different types of properties/methods I can add which will help me serialize selectively (Specified and ShouldSerialize). I noticed in MemberSpecifiedDecorator that the ‘read’ method will set the specified property to true when it reads. However, even if I add specified properties for each field, I’d have to check each one (and update code when new properties were added)
My current plan is to create a custom SerializationContext.context object, and then detect that during the desearalization process – and update a list of members. However… there are quite a few places in the code I need to touch to do that, and I’d rather do it using an existing system if possible.
It is much more desirable to get a list of updated member information. I realize that due to walking down an object graph that may result in many members, but in my use case I’m not merging complex objects, just simple POCO’s with value type properties.
Getting a delta log isn't an inbuilt feature, partly because of the complexity when it comes to complex models, as you note. The Specified trick would work, although this isn't the purpose it was designed for - but to avoid adding complexity to your own code,that would be something best handled via reflection, perhaps using the Expression API for performance. Another approach might be to use a ProtoReader to know in advance which fields will be touched, but that demands an understanding of the field-number/member map (which can be queried via RuntimeTypeModel).
Are you using habd-crafted models? Or are you using protogen? Yet another option would be to have code in the setters that logs changes somewhere. I don't think protogen currently emits partial method hooks, but it possibly could.
But let me turn this around: it isn't a feature that is built in right now, and it is somewhat limited due to complexity anyway, but: what would a "good" API for this look like to you?
As a side note: this isn't really a common features in serializers - you'd have very similar challenges in any mainstream serializer that I can think of.
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.
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.
Getting started with all this MVVM stuff, I was following this post by Josh Smith that talks about an approach to validation while using MVVM. The example is simple, and I began to wonder how I would use it in my own application.
I have, in my BLL, a BookInfo class that implements IDataErrorInfo to report invalid values such as "published date can't be in the future" or "number of pages can't be negative". Then my AddBookViewModel would check the state of the newly created BookInfo, see that errors exist, and the AddBookView will display a red blob next to the appropriate TextBox. That stuff is straightforward, just like in the example in the post.
Now my BookInfo class also holds a list of author IDs. On addition of a new BookInfo to my database, I need to check if those author IDs already exist.
Should this check be done in my BookInfo class? If so, then I would have to pass in my BLL's AuthorManager object to BookInfo's constructor, since the former would contain methods such as CheckIfExists(int authorID).
Is this the recommended approach? What if there are a lot of records in the DB? Dynamically checking would affect performance?
On the other hand, it would seem a bit messy to perform some checks in the BookInfo class and some elsewhere... especially when all those checks can be categorized into the same group... ie. making sure a newly created BookInfo object is valid. Or maybe I'm wrong since I don't really have experience to make proper judgement.
Some guidance?
I wouldn't do this. I would keep the validations done 'inside' IDataErrorInfo simple and contextless. Any validations that depend on context, such as cross-entity validations and validations that are dependent on a database, do that validation when you save the changes.
Trying these more complex context based validations in IDataErrorInfo will be error prone and often impossible. It is often impossible to do this reliably without a context.
I've written a blog post about this. While it is written in the context (no pun intended) of the Validation Application Block, it talks about the general problem of context based validation. It might be helpful. Here it is.
I agree with Steven that you should perform the server-side validations when attempting to save the data.
Another reason for this is network latency. Since WPF's support for IDataErrorInfo uses input events to determine when properties are validated, and results in a blocking/synchronous call to your VM object, the use of IDataErrorInfo has a direct impact on the responsiveness of the UI. You cannot begin an async call to your database to perform the validation and then dispatch validation errors to the UI thread when your network call completes. You would have to make a blocking call to your DB to get the result, which could wreak havoc on the UI thread while it waits for the call to return.
I hope someday WPF gets Silverlight's fancy new INotifyDataErrorInfo interface, which allows for the async validation scenario I described above.