47499

PostSharp & classes that (are supposed to) implement INotifyPropertyChanged

I'm new to PostSharp and am trying to figure out whether it can make my life implementing property changed events a bit easier. However, I'm facing the first issue already. I have my interfaces in one Project library, interfaces.dll:

public interface IPerson : INotifyPropertyChanged { string firstName { get; set; } }

and the implementation in another one, implementations.dll :

[NotifyPropertyChanged] // Postsharp attribute public class Person : IPerson { public string firstName { get; set; } }

However, this doesn't compile as PostSharp only interjects is code after compilation, so the INotifyPropertyChanged implementation is missing at compile time and hence, that aborts with an error.

I'm aware I could just set up the interface IPerson without dependency on INotifyPropertyChanged and everything will work just as intended, but isn't this pretty bad code then? Of course I (or rather, postsharp) will implement the INotifyPropertyChanged methods by itself when set up correctly, but there is no formal definition that IPerson must implement this, so it'd be possible to create an implementation without this, which would lead to odd and potentially hard-to-trace errors. And whenever I want to use INotifyPropertyChanged methods, I'd have to cast Person to this type expiclitly, without having any guarantees it does actually implement the interface.

I'm also aware I could just implement the PropertyChanged handler in Person myself, and PostSharp would at least take care of raising the event. But then again I'm using PostSharp for the sole purpose of managing all that by itself, so it I have to start coding half of that stuff again by myself, I'm not sure it'd be worth using.

So how do you guys handle this? Is there any best practice for this?

Answer1:

If your class implements INotifyPropertyChange then PostSharp requires OnPropertyChanged to be present in the class and expects that you implement it on your own.

Edit: The implementation of OnPropertyChanged could be something like this:

[NotifyPropertyChanged] public class Person : IPerson { public event PropertyChangedEventHandler PropertyChanged; protected virtual void OnPropertyChanged(string propertyName) { PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); } }

PostSharp cannot raise event universally because of CLI limitations. So it has to use this workaround.

NotifyPropertyChanged can be applied to interfaces as well - all interface implementations will implement INotifyPropertyChanged:

[NotifyPropertyChanged] public interface IPerson ... public class Person : IPerson ...

Unfortunately you have to cast to INotifyPropertyChange explicitly but at least you can do that in a safe way:

var person = new Person(); Post.Cast<Person, INotifyPropertyChanged>(person).PropertyChanged += ...

There will be a compile time error when the person instance doesn't implement INotifyPropertyChanged and there will be no warning when it does.

Answer2:

I don't think it's bad code to not inherit INotifyPropertyChanged in the interface. To the contrary, most of the time I have an interface for my data, like your IPerson and then two to three implementations, where at least one does explicitly not implement INotifyPropertyChanged because it's a console or server implementation.

Recommend

  • grunt build Aborted due to warning “Destination not written because minified HTML was empty” and “Pa
  • how to use cmake that installed in a non-standard path?
  • Embedding script with timeout in case server goes down
  • CORS error in PouchDB with CORS enabled in CouchDB
  • How to force Composer to download a local package?
  • Mockery and Laravel constructor injection
  • How to access recipient on sent messages page with mailboxer
  • How do you create a Fuseki SPARQL server using the Apache Jena Java API?
  • OSX - always hide certain files
  • NUnit 3.0 TestCase const custom object arguments
  • Looking for good analogy/examples for monitor verses semaphore
  • Silverlight DependencyProperty.SetCurrentValue Equivalent
  • Tamper-proof configuration files in .NET?
  • Groovy: Unexpected token “:”
  • Control modification in presentation layer
  • Read text file and split every line in MSBuild
  • Does CUDA 5 support STL or THRUST inside the device code?
  • WinForms: two way TextBox problem
  • Weird JavaScript statement, what does it mean?
  • R: gsub and capture
  • jqPlot EnhancedLegendRenderer plugin does not toggle series for Pie charts
  • Comma separated Values
  • Hits per day in Google Big Query
  • Why joiner is not used after Sequence generator or Update statergy
  • how does django model after text[] in postgresql [duplicate]
  • FormattedException instead of throw new Exception(string.Format(…)) in .NET
  • Java static initializers and reflection
  • Exception on Android 4.0 `android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode)`
  • Can Visual Studio XAML designer handle font family names with spaces as a resource?
  • File not found error Google Drive API
  • Qt: Run a script BEFORE make
  • Linking SubReports Without LinkChild/LinkMaster
  • How can I remove ASP.NET Designer.cs files?
  • Are Kotlin's Float, Int etc optimised to built-in types in the JVM? [duplicate]
  • Is it possible to post an object from jquery to bottle.py?
  • unknown Exception android
  • XCode 8, some methods disappeared ? ex: layoutAttributesClass() -> AnyClass
  • Observable and ngFor in Angular 2
  • Unable to use reactive element in my shiny app
  • How to load view controller without button in storyboard?