Today we’re excited to announce the general availability of PostSharp 4, the newest version of our 100%-compatible productivity extension to C# and VB. PostSharp allows developers and architects to automate the implementation of design patterns by encapsulating them into reusable components named aspects. Unlike other development productivity tools, PostSharp does not just make it easier to type code, but results in a smaller codebase that is easier to understand and has fewer defects.

You can download PostSharp 4 today from Visual Studio Gallery and update your projects using NuGet.

PostSharp 4 applies the success of pattern-driven development to the realm of multithreaded applications and provides a thread-safe extension to C# and VB. Application developers can annotate their classes with custom attributes such as [Immutable], [Actor] or [Synchronized] and have their code automatically validated against the model. Any violations result in build-time errors or run-time exceptions instead of data corruptions.

PostSharp 4 makes it incredibly easy to implement undo/redo in desktop and mobile applications by automatically recording changes in model objects. Additionally, it includes more than 15 other improvements and enhancements.

Information in this release announcement includes:

Threading Models

When comparing modern object-oriented programming to assembly language, one can see that notions like classes, fields, variables or methods really simplify developers’ lives and increase their productivity. But when it comes to multithreading, one cannot state that object oriented programming (OOP) delivers so much value. As a result, multithreading is still being addressed at a low level of abstraction with locks, events or interlocked accesses. The resulting cost for the industry, in terms of development effort and number of defects, is enormous.

Alternatives to OOP like functional programming and actor programming have been proposed to address the challenges of multithreading. However, these paradigms are not as appropriate as OOP for business and mobile applications. They have failed to gain wide adoption, existing only in narrow niches where high performance wins over high development cost.

Instead of trying to replace OOP, PostSharp 4 extends the C# and VB languages with custom attributes like [Immutable], [ThreadAffine], [Synchronized] or [Actor], which allow developers to assign a threading model to a class. Based on these custom attributes, the compiler extension validates the code against the model and generates synchronization or dispatching instructions.

PostSharp 4 implements the following threading models:

  • Immutable and Freezable;
  • Synchronized and Reader-Writer Synchronized;
  • Actor;
  • Thread Affine and Thread Unsafe.

What are the benefits?

Thanks to threading models, source code is safer and simpler. Threading models bring the same kind of productivity gains than the stricter C#/VB memory model brought to C++. Source code is more concise and easier to reason about and there are far fewer chances for non-deterministic data races. Threading models make it easier for everyone on the team, not just for multithreading experts, to build robust business applications.

Why is this a significant innovation?

We believe that our approach to multithreading is innovative in many ways, and that its significance exceeds the scope of the PostSharp community. Points of interest include the focus on business applications and average developers (instead of critical software and expert developers); the idea that several threading models can co-exist in the same application as an extension of a mainstream language (instead of requiring a rewrite in a specialized language); and the use of UML aggregation as a foundation to select the synchronization granularity.

See our technical white paper for more details about our approach. We think this new approach could be applied to other object-oriented languages and environments.

Additional Resources

For more information, see:

Undo/Redo

A feature that always scores at the top of each the wish list of each application is undo/redo. Oddly enough, the feature usually remains unaddressed for years because it is awfully painful to implement using conventional technologies. It simply generates too much boilerplate code.

PostSharp 4 takes the boilerplate code out of way. Just add the [Recordable] attribute to your model classes, and they will start appending any change into a Recorder. You can then use the Undo and Redo methods of the Recorder, or add the off-the-shelf WPF buttons to your toolbar.

What are the benefits?

PostSharp 4 makes undo/redo affordable for virtually any application, even line-of-business software that typically has a large object model and a small user base. Previously, the feature had a prohibitive cost and would pay off only in simple applications or software with a large customer base.

The Recordable pattern offers more flexibility than the traditional Memento pattern, and its implementation can be completely automated by the compiler. It demonstrates how better compiler technologies can lead to simpler source code and reduced development effort.

Additional Resources

For more information, see:

Aggregation and Composition

When we built our threading models and undo/redo feature, we realized that we needed a notion of parent-child relationships. When we kept thinking deeper about that, it became clear that most object designs actually relied on this notion. It’s not surprising if one considers that aggregation and composition are core concepts of the UML specification. Yet, it’s a pity it has not been implemented in programming languages. We needed to fix that.

Classes that can be involved in parent-child relationships must be annotated with the [Aggregatable] custom attribute, or with any other attribute that implicitly provides the Aggregatable aspect. Then fields that hold a reference to another object must be annotated with [Child], [Reference] or [Parent].

The principal role of the Aggregatable aspect is simply to automatically set the parent property when a child is assigned to a parent and to implement a child visitor.

For more information, see:

Other Improvements

In addition to the previously described new features, we significantly enhanced the PostSharp Aspect Framework and worked on other components as well:

More Free Aspects in PostSharp Express

PostSharp 4 generalizes the idea of giving our ready-made pattern libraries for free for small projects. PostSharp Express 4 now includes the following features for free – for up to 10 classes per Visual Studio project:

  • NotifyPropertyChanged
  • Recordable, EditableObject (undo/redo)
  • Aggregatable, Disposable
  • Threading (threading models, dispatching)
  • Code Contracts
  • Logging (up to 50 methods)

If you like the new features and want to use them more, you can buy them as a part of PostSharp Ultimate or as an individual product. More on our pricing page.

Platforms Newly Supported

PostSharp 4 adds full support for:

  • Win RT both on Windows 8 (the previous support was error-prone and needed a complete redesign) and Windows Phone 8.1.
  • Windows Phone 8.1 “Silverlight”.
  • C++ “mixed mode” assembly references.

Platforms No Longer Supported

We decided that new releases of PostSharp would not support platforms for which Microsoft no longer provides mainstream support at the time of a PostSharp RTM release.

On development workstations and build machines, PostSharp 4 no longer supports:

  • Windows XP (Vista, 7 or 8 is required).
  • Visual Studio 2010 (2012 or 2013 is required).
  • .NET Framework 4.0 (4.5 is required).

On end-user devices, PostSharp 4 no longer supports:

  • .NET Framework 2.0 (3.5, 4.0 or 4.5 is required).
  • Windows Phone 7 (8 or 8.1 is required).
  • Silverlight 4 (5 is required).

Note that PostSharp 3.1 still supports these platforms.

Summary

While Microsoft has lately been catching up with its competitors in the consumer market, enterprise developers may feel neglected. At PostSharp, our focus is to increase productivity of large .NET development teams. It’s only when you start counting lines of code with 6 or 7 digits – and you realize that every line may cost your employer between $10 and $20 – that you appreciate and receive the full benefits of automating design patterns.

PostSharp 4 marks a significant innovation in the realm of multithreading. It raises the level of abstraction by defining models so the machine can do more and humans must think less. But instead of requiring developers to switch to a different language, it respects their investments in C# and VB and extends the environment in a backward compatible fashion.

PostSharp 4 includes plenty of important new features including undo/redo, parent-child relationships, performance improvements, new advices and more.

It’s an exciting time to be a developer.

Happy PostSharping!

-gael

When we built the undo/redo and threading models features of PostSharp 4.0, we needed had to address the problem of aspect dependencies. Both the Recordable and threading models aspects require the Aggregatable aspect. If the Aggregatable aspect is not present, it should be added automatically.

Checking whether an aspect has been added to a declaration

Adding a dependent aspect automatically is easy: it can be done with the IAspectProvider. What’s more difficult is to know whether an aspect has already been added to a declaration. The aspect can have been added as a custom attribute, as a multicast custom attribute, and in these cases the ReflectionSearch.GetCustomAttributesOnTarget method would do the job. But they also be added dynamically using through IAspectProvider, and up to now there was no API to reflect dynamically added aspects. That’s why we added the IAspectRepositoryService interface. It has two interesting features:

  • GetAspectInstances and HasAspect methods: Query aspects on a given declaration.
  • AspectDiscoveryCompleted event: Event raise after all aspects have been discovered and initialized.

To check whether an aspect has been added to a declaration, the following code is typically used in the implementation of IAspectProvider.

PostSharpEnvironment.CurrentProject.GetService<IAspectRepositoryService>.HasAspect( declaration, typeof(Aspect) )

Late validations

Sometimes it is necessary to programmatically validate code against the presence of aspects. This validation can be done only after all dynamic aspect providers (IAspectProvider) have been executed. For instance, child fields of an immutable class must have be themselves immutable or freezable, which means that, unless this is an intrinsically immutable type like int or string, the aspect must have the Immutable or Freezable aspect.

This is why we have the AspectDiscoveryCompleted event on the IAspectRepositoryService interface. It allows aspects to execute code at build time after all aspects have been discovered

Summary

Technically, the new service IAspectRepositoryService allows you to cope with complex dependencies between aspects. But more fundamentally, the feature allows you to create real language extensions composed of several aspects and custom attributes that play well together.

Happy PostSharping!

-gael

As we’re progressing in the RC cycle of PostSharp 4.0, I would like to shed some light on a feature that has been often requested in the past, and is finally available in PostSharp 4.0: OnInstanceConstructedAdvice.

The objective of this advice is to provide a way for the aspect to execute code when instances of the target class are “fully constructed”. What does that mean to be “fully constructed”? In short, it means that all instance constructors in the chain have been invoked. Note that it is not the same as having an OnSuccess advice on the public constructor: such advice would be executed even if the current constructor is not the last in the chain.

Example

Let’s see this on a simple example.Here’s an aspect that has both kinds of advices:

[PSerializable]
class MyAspect : InstanceLevelAspect
{
    private Type appliedTo;

    public override void CompileTimeInitialize(Type type, AspectInfo aspectInfo)
    {
        this.appliedTo = type;
    }

    [OnInstanceConstructedAdvice]
    public void OnInstanceConstructed()
    {
        Console.WriteLine("OnInstanceConstructed({0})", this.appliedTo);
    }

    [OnMethodSuccessAdvice, MulticastPointcut(MemberName = ".ctor")]
    public void OnSuccess(MethodExecutionArgs args)
    {
        Console.WriteLine("OnSuccess({0})", this.appliedTo);
    }
}

And here is some testing code:

[MyAspect]
class Foo
{
    public Foo()
    {
Console.WriteLine("Foo()"); } public Foo(int foo) : this() {
Console.WriteLine("Foo(int)"); } } static class Program { public static void Main() { Foo foo = new Foo(0); } }

The program is instantiating Foo by invoking a constructor that chains another constructor. Its output is the following:

Foo()
OnSuccess(ConsoleApplication7.Foo)
Foo(int)
OnSuccess(ConsoleApplication7.Foo)
OnInstanceConstructed(ConsoleApplication7.Foo)

As you can see, the OnSuccess advice has been invoked twice because two constructors were chained. However, OnInstanceConstructed was invoked only once after the last constructor completed.

Let’s have a more complex example:

[MyAspect]
class Bar : Foo
{
    public Bar() 
    {
Console.WriteLine("Bar()"); } public Bar(int bar) : this() {
Console.WriteLine("Bar(int)"); } } static class Program { public static void Main() { Bar bar = new Bar(0); } }

The output is the following:

Foo()
OnSuccess(ConsoleApplication7.Foo)
Bar()
OnSuccess(ConsoleApplication7.Bar)
Bar(int)
OnSuccess(ConsoleApplication7.Bar)
OnInstanceConstructed(ConsoleApplication7.Foo) OnInstanceConstructed(ConsoleApplication7.Bar)

As expected, OnSuccess is invoked twice. It may be more surprising to see OnInstanceConstructed invoked twice. The reason is that the method is actually called only once, but once for each instance of the aspect, and here we have two instances of MyAspect: one on Foo, and the other on Bar.

If you want to have a single execution of the logic, you have to make it conditional to this.appliedOnType:

[OnInstanceConstructedAdvice]
public void OnInstanceConstructed()
{
    if (this.appliedTo == this.Instance.GetType())
    {
        Console.WriteLine("OnInstanceConstructed({0})", this.appliedTo);
    }
}

How does it work?

The OnInstanceConstructed advice needs to “know” that the constructor is the last in the chain.

Let’s look at the code after it has been transformed by PostSharp:

internal class Bar : Foo
{
    public Bar() : this(ConstructorDepth.Zero)
    {
    }

    protected Bar(ConstructorDepth __depth) : base(__depth.Increment())
    {
        Console.WriteLine("Bar");
        this.<>z__aspect2.OnSuccess(null);
        if (__depth.IsZero)
        {
            this.OnInstanceConstructed();
        }
    }

    public Bar(int bar) : this(bar, ConstructorDepth.Zero)
    {
    }

    protected Bar(int bar, ConstructorDepth __depth) : this(__depth.Increment())
    {
        Console.WriteLine("Bar(int)");
        this.<>z__aspect2.OnSuccess(null);
        if (__depth.IsZero)
        {
            this.OnInstanceConstructed();
        }
    }

    protected override void OnInstanceConstructed()
    {
        base.OnInstanceConstructed();
        this.<>z__aspect2.OnInstanceConstructed();
    }
}

As you can see, PostSharp does three things with every user-defined constructor:

  • Add an argument of type ConstructorDepth to the original constructor.
  • Create a new constructor with the original constructor signature, which invokes the original constructor (with the modified signature) with the parameter ConstructorDepth.Zero.
  • In the constructor chain, add the argument __depth.Increment() to the original invocation.

Therefore, we know when the current constructor depth is zero and we’re able to invoke OnInstanceConstructed. If you’re looking at your code with System.Reflection, you will see that there are twice as many constructors. Naturally, you should invoke only the public or internal constructors, which have the original signature and initialize the depth to zero. Except reflection, the modification is harmless to user code.

Summary

The OnInstanceConstructed advice is the only reliable way to execute logic in the aspect only once after the instance has been fully constructed. We needed this feature to implement Aggregatable, Undo/Redo and Threading Models in PostSharp 4.0, and made it in a way that can be useful to everybody.

Happy PostSharping!