When we announced PostSharp 3.2 Preview, many of you shared your experience about the new features – especially threading models and undo/redo. We found it was such a significant release it would deserve a major version increase. So today, we’re proud to announce the availability of PostSharp 4.0 RC. There will be no PostSharp 3.2 release. PostSharp 3.2 has just been renumbered 4.0.
You can download PostSharp 4.0 RC from our web site. After you install the Visual Studio Extension, you can update your existing projects using NuGet Package Manager, by enabling the “pre-release” option.
What’s New in PostSharp 4.0?
Write thread-safe code in C# and VB using threading design patterns
Multithreading is difficult because we are reasoning about it at an absurdly low level of abstraction. Functional programming languages attempt to solve this problem by forcing you into a specific threading design pattern: Immutable Object. However, object-oriented programming is the right paradigm for most business applications.
PostSharp 4.0 brings the benefits of threading patterns to C# and VB. Instead of migrating your whole project to a different language, mark individual classes with one of the following custom attributes: [Actor], [Immutable], [Freezable], [Synchronized], [ReaderWriterSynchronized], [ThreadAffine] or (the anti-model) [ThreadUnsafe]. PostSharp will then ensure that your code is correct against the model, and will block you deterministically if this is not the case.
For more information, read Working with Threading Models in our documentation.
Implement Undo/Redo at model level
Undo/redo is one of the most-wanted features, but it is often absent from custom applications because it is so expensive to implement. There is no longer an excuse. The new [Recordable] aspect causes any change to your classes to be recorded, so they can be undone at any time. We provide ready-made buttons for WPF, but you can also build your own easily for Windows Phone or Windows 8.
For more information, read Implementing Undo/Redo in our documentation.
Aggregatable and Disposable Patterns
Aggregation – the parent/child relationship – is a fundamental concept of object-oriented design and a part of the original UML specification. Several design patterns rely on object aggregation. Despite its importance, the idea has not been implemented into programming languages, and is therefore the cause of much boilerplate code in most business applications.
For more information, read Implementing Parent/Child Relationships in our documentation.
Other enhancements in PostSharp Pattern Libraries
We optimized performance of our famous NotifyPropertyChanged aspect. It is now 4 times faster at runtime.
Improved deadlock detection
The policy now also detects deadlocks involving synchronous calls to the WPF dispatcher.
Enhancements in PostSharp Aspect Framework
In PostSharp 3.1, some advices were purely “static”. Either they were in the aspect, either they were not. In PostSharp 4.0, an aspect can take decisions dynamically about which advices must be added to the target class and members by implementing the IAdviceProvider interface. The interface allows to provide instances of one of the following advices: IntroduceInterface, ImportLocation, ImportMethod, IntroduceMethod.
It is now possible for an aspect to know which other aspects have been added to any declaration thanks to the IAspectRepositoryService. Plus, the AspectDiscoveryComplete event allows to run execute logic (typically for validation) after all aspects have been discovered.
OnInstanceConstructedAdvice lets you execute code after all constructors of a method have completed. We also added InitializeAspectInstanceAdvice, which extends RuntimeInitializeInstance with a parameter telling for which reason the aspect instance is being initialized.
Faster advice state lookup
Thanks to the DeclarationIdentifier property, it is easier to uniquely identify a member within a type. State can now be stored in an array instead of a dictionary, which makes lookups much faster. We use this feature to persist analysis results at build time and consume them at runtime.
Enhancements in PostSharp Core
Support for C++ assembly references
We solved issues where it was not generally possible to add aspects to a C#/VB assembly that referenced a C++ .NET assembly. The previous workaround (which was to use the managed host) is no longer necessary.
Support for WinRT and Windows Phone 8.1
We completely redesigned our support for .NETCore (the intimate name for .NET on Windows 8 and Windows Phone 8.1), and this is now much more reliable than before.
What did we drop in PostSharp 4.0?
Since we’re following the rules of semantic versioning, a new major release is an opportunity to abandon support for features that caused tension in our design and engineering processes. Therefore, we discontinued the following features:
- Silverlight, Windows Phone 7 and Windows Phone 7.5 are no longer supported by the PostSharp Model Pattern Library. The platforms are still supported by the core product itself (PostSharp.dll).
- The IReaderWriterSynchronized interface has been fully deprecated.
PostSharp 3.1 will remain supported for a while and minor bugs will still be fixed. Issues that require important redesign will no longer be addressed in PostSharp 3.1.
Status of PostSharp 4.0 RC
We take the word release candidate seriously at PostSharp. The RC milestone means that the following criteria were fulfilled:
- All planned features are implemented.
- All new APIs have been reviewed and we predict no breaking change will be necessary, even with regard to other envisioned features.
- All features have been tested internally.
- A zero-defect point was reached at the time of release.
- API documentation and tutorials are complete; testers did not report discrepancies or ambiguities in the documentation.
The ball is now in your camp; we need you to try to update your solutions (in a prototype branch) to the new version, run your test suite and report any issue. We will gather feedback during several weeks and promote the release to stable after community testing.
PostSharp 4.0 proposes a realistic approach to thread-safe object-oriented applications. We believe the significance of this innovation exceeds the scope of PostSharp and perhaps even .NET, since the concepts, if proven successful, could be implemented in other programming languages by a new generation of compilers. We’re obviously very proud of this achievement, and can’t wait to get feedback from the field.
Additionally, Windows and Windows Phone developers can now add undo/redo to their application with minimal effort thanks to our new Recordable pattern – a powerful alternative to the Memento pattern.
To realize these two new major features, we had to build new abilities in our aspect framework. You can now rely on these new types of advices to build automation for your own patterns.
We need your feedback to move this release to the stable milestone. Please download it from our web site and let us know what you think.
We didn’t want to let the first half of this year go without reaching a new milestone, and here it is: we’re excited to announce PostSharp 3.2 Preview 2, available for download on NuGet and our website. PostSharp 3.2 is now fully documented and has made it through the final API review.
We didn’t really know where we were heading to when we started to work on this version, but after a six-month journey we’re very happy of the result.
And here’s our proudest achievement:
PostSharp 3.2 allows you to write thread-safe code in C#. I mean, really. No, we don’t magically make your old C# apps thread-safe, but PostSharp 3.2 both extends and restricts C# to define an execution model that is verifiably thread-safe (we call that threading model). It’s still the C# you know: we extend the language using custom attributes, and we enforce the model using build-time and run-time verifications. So, if you write your code against of one of threading models of PostSharp 3.2, and if you cover your code with reasonable single-threaded tests, you are much more likely to have thread-safe code. Unsafe code would trigger build-time errors or deterministic runtime exceptions instead of allowing for random data races.
We would really like to say that if you use PostSharp you’re 100% sure to have 100% thread-safe code, but this would be absurd. No real-life programming language can claim that. What we do claim is that if you use the custom attributes provided by PostSharp 3.2 instead of writing thread synchronization code manually, you will have a dramatic reliability increase and an equally dramatic cost decrease.
PostSharp 3.2 supports the following threading models: Actor, Immutable, Freezable, Synchronized, Reader-Writer Synchronized, Thread-Affine and (the anti-model) Thread-Unsafe. For more information, read Working with Threading Models.
Object-oriented programming is a great paradigm to build business and consumer applications and we really, really don’t like the blind push for functional programming these days here at PostSharp. There is a word to describe this social phenomena: hype. Fortunately, people in charge for 7-plus-digit projects don’t make their decisions based on fashions. Although OOP has been criticized for being unpredictable in multi-threaded scenarios, we’re proving that well-understood technologies such as aspect-oriented programming, static analysis and runtime program verification can be used bring thread safety to mainstream programming languages. We still see bright days for OOP.
Although threading models definitively what we’re the most excited about, PostSharp 3.2 brings much more:
In this article, Alessandro Federici, System Architect at CODY Systems, talks about how and why he is using the Model Pattern Library and shows a pragmatic approach to make the PostSharp Code Contracts play nice with XAML-based applications. He also describes some of the other aspects he built himself: - InstantiateIfNullAspect, StringManipulationAspect and WrapExceptionsAspect.
The source code for this blog post is available for download.
I’ve been using PostSharp for several months at CODY Systems. For the sake of this article, I built a small WPF application that demonstrates our principal use cases. This application is very simple and is split into two assemblies:
- MyCompany.Contracts.dll: a simple assembly with the definition of data contracts such as User, PersonName and Phone. This is an assembly that is meant to be used in WPF client applications, MVC web apps and/or web services (if we were to build any). In addition, this assembly contains all the aspects required for validation and a few other utilities.
- WPFApp.exe: the main executable. It links to the other assembly and contains just one view, its view model and some helper classes.
When you run the application, you will see a dialog that will look like this:
As soon as you change the text of some controls, if the values are invalid and validation rules fail, you will get the following hints being displayed:
The two buttons at the bottom of the dialog show how to trigger validation manually (the 'Validate' button) and how to use my WrapExceptionAspect (the 'Throw Exception' button).
To use IDataErrorInfo/IValidatableObject, or to throw exceptions, this is the question
When you build XAML applications (i.e. WPF, Silverlight or Windows Phone), you are supposed to use the IDataErrorInfo interface to collect errors. These errors are then intercepted by using specific triggers and the collection 'ValidationRules' of the bindings of your view. MVC also respects the interface, although it does so by using the MVC approach to binding and using post-backs.
IValidatableObject is a newer approach in the realm of .Net data validation. It was introduced by MVC 3 and, as far as I know, it is an MVC-only item (by default, at least. You can certainly support it in WPF or Silverlight with some coding).
My main beef with IDataErrorInfo and IValidatableObject is that they expect you not to raise exceptions in property setters which is precisely what the PostSharp Model Patter library does. They treat such situations as something either “bad” or un-common.
In my opinion, property setters that throw exceptions are common and, in many cases, the behavior is a useful feature that makes classes easy to use and understand. The approach follows the same logic of good methods that raise ArgumentNullException(s) or similar exceptions. Good stuff, if you ask me.
For instance, if you were to code a Person class by using IDataErrorInfo guidelines, you would receive no errors assigning Age the value -22 or FirstName a null value. You would not find out about the problem unless you read the Errors property and then acted accordingly.
There are good reasons for designing interfaces that work like this, but in my opinion this is a case where user-interface concerns got mixed up with elements that should follow user-interface-agnostic guidelines.
I understand that sometimes a certain value is invalid only if another property has a specific value (e.g. you cannot have a boolean Juvenile flag being set if the Age is more than 18). Yet, what I found in my experience is that this kind of validation should (more-often-than-not) be delegated to other classes. I call those classes “Validators”.
Complex or cross-property business logic often needs parameters or very configurable rules that might change, depending on the customer. In some systems I worked on, some business rules might be completely eliminated during certain implementations while they could be replaced in their entirety in others Cluttering classes like User, Customer, etc. with those rules usually lead to suboptimal situations (code-wise).
Let me explain by expanding on the Juvenile example above.
The type of software I write relates to law enforcement. If a crime is committed by a Juvenile there are a number of rules that have to be considered. Some rules affect the flow of data (e.g. where are these objects stored? Who can see juveniles and work on them?), others rules determine validity of a Person's object state (e.g. Juvenile can be true if (Age<SysConfiguration.AgeOfAdults) or (Age is null and SysConfiguration.AllowNullAgeForJuveniles)).
The tricky part is that a juvenile is not always a juvenile: what one State considers a juvenile (age of 17) might be considered an adult in another State (e.g. Illinois vs California). If we were to enforce cross-property rules between Juvenile and Age inside the Person class, we'd have to know the configuration of the system inside Person and act accordingly. That, in my opinion, is really not a concern of the Person class.
Person is a class that should never allow a negative Age or a null FirstName. That's about it, and that is what aspects do well. Those rules always make sense, in Person, and belong to the Person “contract”.
The fact a state considers adults at the age of 17 or 18 and the need to check the values of two properties is a problem that originates from ‘where Person’ is used (our system, with a given configuration applied), not what a Person is or should allow for. In addition, it has been advantageous to be able to completely replace certain business logic for some of our customers, so the pluggable 'Validator' played much nicer than embedded (and quasi hard-coded) rules.
Validator classes are then used by view models and server side services (I always double check for such things, as the user of our API might not have access to our C# contract libraries and might need to rely solely on server-side validation).
So, having said this, what I wanted to see is if I can use the PostSharp aspects that ensure 'universal' (i.e. always necessary) object-state integrity, proper formatting of some text (e.g. capitalization of names or other helpful thing of this nature) and, at the same time, build a WPF interface that shows nice errors just like using the IDataErrorInfo interface.
The contracts library is where all the validation rules I choose get defined. The idea is to create a set of classes that are reusable regardless of the user-interface framework you will build clients with. WPF, ASP.Net, ASP MVC... It shouldn't matter. Actually it shouldn't matter if you have a user-interface layer at all. Business contracts should work even without a client and allow you to just write a web service API which is used as-is.
The contracts library in the sample application is very simple. It defines three classes: User, PersonName and Phones. User is defined as follows:
As you can see, there isn't much to it, except an abundance of aspects.
The properties Age and EMail use two aspects that should be obvious to anybody reading the code. That is a very important part of using aspects: they often help making behavior obvious and forego the need to read documentation or dive into code. Range and EmailAddress are part of the Model Pattern Library shipped with PostSharp 3.0. The first will check that the Age is positive and won't allow values bigger than 110. The second will ensure that the email address is properly typed (i.e. firstname.lastname@example.org).
INotifyPropertyChanged No More
At the very top of the class, I used the well-known NotifyPropertyChanged aspect that is probably the most used and most famous aspect that ships with PostSharp. That aspect alone probably eliminated half the code needed to implement the class User. The feature will come handy in WPF and Silverlight apps and it will have no noticeable impact on an MVC app or a web service.
It's also possible to have code that inspects properties and, by looking at what aspects are applied to them, can generate automatic tooltips or verbose documentation.
My Custom Aspects
The Name property is decorated with my very own InstantiateIfNullAspect. That aspect (which I included in this sample) creates instances of the property it is applied to, without the need for repetitive code such as “if (_name==null) _name = new PersonName(); return _name;”. I use this aspect extensively in my contracts library. It allows me to create a new Person and immediately start populating its pieces without thinking about nulls or redundant extra code.
You can see this in the CreateDesignTimeData() method of the view model:
The principle that guides its use, for me, is the following: certain parts of a class (owner) might be defined using other classes, but the owner describes something that would not make sense without the other piece(s). Whenever this rule is met, it probably makes sense to use InstantiateIfNotNullAspect, auto-create inner instances and cut all the boiler-plate code that would be otherwise necessary (especially in the calling code, which is much easier to plague with NullReferenceException(s)).
While the aspect supports interfaces (e.g. you can have a property of type IList and specify that the 'ConcreteType' you want to use to create it is either List, ObservableCollection, etc.), I rarely use it with interfaces. I leave those as properties that are to be filled in, for instance, after fetching data from the server. The fact those properties are null are a reminder that a web-service fetch is necessary. It's up to you to decide if this fits with your needs or not, but I wanted to mention it.
The PersonName class is similar, but I user more aspects, including my StringManipulationAspect. This aspect changes strings by performing one or many common transformations (e.g. remove some type of characters, capitalize text, lower-case it, upper-case it, etc.) that we often need in applications.
Once again, pretty obvious to understand, thanks to aspects.
The Application's View
As you would expect from any decent MVVM application, the view is 99.99% code-free. Specifically, the only code in the main view is the automatically-generated constructor.
The interesting parts are in the XAML code.
The first thing I did was to define a couple of resources that will be needed for my error interception.
The first is a converter ('ErrorMessageConverter') which is capable of getting an exception message and convert it to nicely readable text. This was necessary because the messages coming from the PostSharp validation aspects don't read well (as tool-tips), even if we provided our own error text like I did in the properties First and Last of the class PersonName. Some text-transformations were necessary and the nicer text is what will be displayed by the tool-tips, whenever a validation rule is violated.
The second resource is a style that I want applied to all TextBox(es). This style contains a trigger that binds to the error that was raised (if an error was raised) and uses the previously defined converter 'ErrorMessageConverter'.
With these two resources, I can now continue my XAML coding and have all TextBoxes react to errors by displaying a red box and a tool-tip just adding an ExceptionValidationRule element to its binding:
The purpose of the button 'Validate' is to show how to invoke validation manually. This is something you will need if the form starts without data and you want to guide the user actions. To see it work, enable the commented code in the constructor of the view model, run the application and then click the button.
What happens, when you run the application, is the following: a regular Exception is thrown with the message 'This is the inner exception (…)'. The aspect catches that and wraps it in a GuiException whose message then becomes 'An unexpected error occurred. The error was 'This is the inner exception (…)''.
It's easy to get in situations where some exceptions occur and you don't immediately know what caused them. Often we are given mysterious and miss-leading bug reports that read as 'A 'NullReference crash occurred when I clicked the button', or more nonsense like that.
When I read those reports, I usually get angry for two reasons: the completely useless error report and, right after, the knowledge that I have no immediate pointer to what really happened. The WrapExceptionAspect allows me to wrap exceptions into more meaningful ones, so that I immediately know the area where the problem occurred. Obviously all that happens automatically, since we use aspects.
Server-side, in my web servoces, I tend to create exception types for each area of my API (e.g. FileService, ImageService, SecurityService etc. with the relative FileServiceException, ImageServiceException and SecurityServiceException) and I then wrap the accessible web-methods with the aspect. What happens then is that, instead of getting useless NullReferenceException(s), I get xxxServiceException(s) that wrap the other errors (whatever they are). The exception now immediately points me to the right area so I can focus my attention on the right service or area.
The Model Pattern Library is a great addition to the arsenal provided by PostSharp. While powerful, very easy to use and fall in love with, it's hard to use the validation aspects cleanly, in XAML applications. This article showed a possible solution to the problem so you can plug validation aspects in XAML front-ends without having to duplicate validation logic in IDataErrorInfo of IValidatableObject interfaces.