PostSharp on cloud

1-click AWS Deployment    1-click Azure Deployment

Overview

PostSharp is available from SharpCrafters s.r.o.. A free Starter Edition providing the most commonly used aspect types is available, and supports commercial applications with a royalty-free runtime. The Starter Edition can be downloaded from the SharpCrafters site. Installation via the PostSharp NuGet package is recommended for those interested in the Pro version. All editions of Visual Studio 2010 are supported.

PostSharp Pro extends the Starter Edition by adding the ability to implement more complex aspect scenarios, plus enhancements to the Visual Studio 2010 IDE with an Aspect Browser window and visual indicators in the code editor. PostSharp is installed into the folder C:\Program Files\PostSharp 2.1 on 32-bit Windows.

PostSharp began as an open source project by Gael Fraiteur in 2004, with the first stable release in 2007. As PostSharp grew in popularity, Fraiteur founded SharpCrafters in 2009 to allow him to devote his efforts to PostSharp full-time. The commercial launch of PostSharp Pro came in March 2010. SharpCrafters is headquartered in Prague, Czech Republic.

Aspect-Oriented Programming with PostSharp:

How Does PostSharp Work:
Once PostSharp is installed, you encapsulate the desired crosscutting functionality into an aspect method and then apply that aspect individually to the desired classes or methods within the application, either declaratively using attributes, or to a namespace using a multicast attribute.

PostSharp uses a post-compilation approach by modifying the Microsoft Intermediate Language (MSIL) to include the aspect behaviors. This makes PostSharp .NET language-independent, as all .NET languages ultimately produce MSIL output. MSIL is extensively documented in the ECMA-335 standard specification. MSIL transformation is also used by Microsoft in code contracts and is fully supported.

Aspects must be marked Serializable, because the aspect code is serialized and added to the .NET assembly as a managed resource so it can be available at runtime.

PostSharp is build server friendly. As part of the build process, PostSharp can and should be integrated with the build server process; if PostSharp is deployed to the source code repository, it doesn’t need to be installed on the build server. If installed on the build server, PostSharp has a minimal UI, which can be suppressed with registry settings. PostSharp doesn’t require a separate license for the build server. PostSharp supports code obfuscation to discourage reverse engineering the source code

Coding an Exception Handler Aspect in Visual Basic
The aspect base class OnExceptionAspect is one of the commonly used aspects, and is available in the free PostSharp Starter Edition. This aspect wraps around the target method with a try-catch construct and provides the OnEntry, OnSuccess, OnException and OnExit advices. An advice is anything that adds a behavior or structural element to source code. In this case, an advice can be thought of as one of the overrideable methods in a PostSharp aspect.

Listing 1 shows a console application implementation of the aspect OnExceptionAspect. It provides the useful behavior of logging technical details of an exception for later investigation, while preventing potentially undesirable technical details, such as a connection string or resource path, from being shown to the user.

The aspect ExceptionWrapper generates a series of technical messages identified by a GUID to the Debug output window when an exception occurs. This simulates what would be logged when an exception occurs. It then throws a new exception with a user-friendly message to contact support for this Error ID. The original exception is carried as the innerException so that the calling routine retains full flexibility in how to handle the exception. The code in Listing 1 plus a reference to the PostSharp assembly was all that was needed to create this example in Visual Studio 2010 after PostSharp was installed.

Looking at Listing 1, the aspect is applied to the CreateError method using an attribute. No error-handling code is present within the method, yet it receives the full benefit of the custom error-handling logic in the ExecutionWrapper aspect. Coding the aspect involves creating a serializable class that inherits from the desired base class aspect, OnExceptionAspect.

The base class provides a series of methods that do nothing until overridden. In order to write trace messages in the case of an exception, ExceptionWrapper overrides the OnException advice and adds the desired behavior. The MethodExecutionArgs parameter provides the needed information about the exception that was thrown.

Figure 1 shows the output of the example. The trace messages in the first four lines were written by PostSharp because an error occurred in a method decorated by the ExceptionWrapper attribute. The last line shows the suggested non-technical error message shown to the user.

 

What if the ExceptionAspect should handle only certain exception types for a particular target? How are these exception types specified, and how does the aspect respond to only those exception types?

Listing 2 shows how the GetExceptionType method can be overridden in the ExceptionWrapper class to filter the exception types for the aspect. The commented attributes show the various ways the attribute can decorate the target method with parameters, for either a single exception type or multiple exception types. If the GetExceptionType method returns an exception type matching the current exception during application execution, then it’s handled; otherwise, it’s ignored.

Multicast
The PostSharp Starter Edition supports OnMethodBoundaryAspect. It’s invoked each time the method is called, and it, too, supports the OnEntry, OnSuccess, OnException and OnExit advices. This aspect is appropriate for implementing tracing or execution instrumentation by tracking entry and exit of the desired target methods or classes.

Decorating each method with an attribute isn’t practical for the large number of target methods that might be involved in tracing or instrumentation. For this you need the PostSharp multicasting capability, which allows an aspect to be applied to multiple targets by adding a directive to the AssemblyInfo.vb file. Multicast is how an aspect can be applied to an assembly without directly modifying the target source code.

The first Assembly directive in the following code applies the TracingWrapper aspect to all classes and methods in the MyApp.BusinessLayer namespace, including constructors. If you wish to limit the aspect to only methods of a certain name, you could use an Assembly directive similar to the second, which limits the instrumentation to only those methods that contain “InsertRecord” in the method name:

 <Assembly: MyApp.TracingWrapper(AttributeTargetTypes:="MyApp.BusinessLayer") > 

 <Assembly: MyApp.InstrumentationWrapper(AttributeTargetMembers:="*InsertRecord*") >

When attempting to multicast an aspect, be sure to test it as an attribute on a single method first, to ensure it works properly.

Enhancing Role-Based Security
Declarative role-based security is supported in standard .NET applications, such as restricting a method to members of a list of roles. What if the business requirement is to restrict the users to performing functions for only their own business unit? Let’s use the PostSharp Starter Edition to create a realistic purchasing scenario where employees can only requisition items for their own business unit.

Listing 3 demonstrates how to use the OnMethodBoundaryAspect to validate that only authenticated users can execute the method, and to only authenticate users whose UserSecurityInfo.BusinessUnit property matches the BusinessUnit parameter passed into the method. The assumption is that the application will prompt for the desired business unit before displaying the purchasing requisition form, and pass that in as a parameter to the CreateRequisition method.

Listing 3 overrides the OnEntry advice to determine if the user is authorized for that business unit. It demonstrates the ability to view the parameter values of the target method for use in the aspect’s decision logic. The BusinessUnit parameter can appear anywhere in the target method parameter list, but must be called exactly “BusinessUnit.” By overriding the RuntimeInitialize method, the aspect ensures that the user security table has been initialized prior to its use. The aspect doesn’t check security if the target method is the constructor.

As you can see, some rather advanced security was applied to a method simply by decorating it with the ValidateBusinessUnit attribute.

Compatibility and Platforms
PostSharp is compatible with Visual Studio 2008 and Visual Studio 2010. The IDE enhancements are available only with the Pro version, and are not compatible with the Express version, as it doesn’t support any IDE extensions. SharpCrafters has confirmed that Windows 8 (including the Windows Runtime) and Visual Studio 2012 will be supported in PostSharp 3.0, which is currently under development.

PostSharp can be used with Silverlight, the .NET Compact Framework and Windows Phone. Separate reference assemblies are provided for these environments. PostSharp 3.0 will use the Portable Class Library so that a common codebase can be used across the .NET platforms.

A New Aspect to Your Coding
I hope this article has helped you understand what AOP is and how it can simplify your coding experience without sacrificing desired functionality. I only scratched the surface of what can be done with AOP as implemented by PostSharp. I plan to incorporate AOP as a routine part of my coding efforts so that I can focus more on business logic and less on routine repetitive code, and gain some significant time savings. Maybe I’ll even gain enough time for a vacation away from my computer!

PostSharp is the #1 pattern-aware extension to C# and VB. It allows developers to eradicate boilerplate by offloading repeating work from humans to machines. PostSharp contains ready-made implementations of the most common patterns and gives you the tools to build automation for your own patterns.

Developers usually think in terms of design patterns, but with conventional programming languages, they end up writing boilerplate code. PostSharp extends the C# and VB languages with a notion of pattern. The result: shorter, cleaner code that’s easier to write and understand, contains fewer defects and is less expensive to maintain.

PostSharp is the #1 pattern-aware extension to C# and VB. It allows developers to eradicate boilerplate by offloading repeating work from humans to machines. PostSharp contains ready-made implementations of the most common patterns and gives you the tools to build automation for your own patterns. 

  1. PostSharpwith Visual Studio 

A single download for all editions and licenses. Available features will vary according to the license key you enter. 

  1. PostSharpNuGet Packages 

You can download NuGet packages for PostSharp but note that the debugging experience may be inconsistent with other IDEs than Visual studio or when PostSharp Tools for Visual Studio are not installed. 

PostSharp: Free Yourself from Repetitive Code 

PostSharp is the #1 pattern-aware extension to C# and VB. 

As developers, we usually think in terms of design patterns but with conventional programming languages which lack support for implementing patterns, we end up writing repetitive code. PostSharp solves this by extending the C# and VB languages with a notion of pattern. It includes ready-made implementations of the most common patterns found in .NET and gives you a framework to automate your own patterns. 

The result: shorter, cleaner code that’s easier to write and understand, contains fewer defects and is less expensive to maintain. 

PostSharp is a commercially-developed product with a highly popular free edition named PostSharp Community. 

Over 50,000 developers and more than 10% of Fortune 500 companies including Microsoft, Intel, Bank of America, Volkswagen, BP, Siemens, and Oracle rely on PostSharp to save 10 – 25 % lines of code and thus: 

  1. Reduce development costs and deliver faster. 
  1. Build more reliable software. 
  1. Add functionality more easily after the first release. 
  1. Get new team members productive quicker. 

PostSharp includes the following components: 

PostSharp Framework: the #1 aspect-oriented framework for .NET 

Automate your own patterns with aspect-oriented programming: 

  • The most comprehensive aspect-oriented framework for .NET, hands down. 
  • Exceptional performance. 
  • Full support for async methods. 

Automate your code reviews with architecture validation: 

  • Validate your code at build time with the familiar System.Reflection API. 
  • Emit errors and warnings into the IDE. 
  • Leverage the full power of PostSharp analytics such as used-used-by relationships, parent-descendant relationships, method decompilers, and more. 

 

PostSharp Logging: the no-brainer instrumentation toolbox for .NET 

Add extensive logging to your application in minutes and direct it to any logging framework.
Your way, faster than hand-written code. 

  • Super easy. You’ll be done in minutes. 
  • Super detailed. See parameter values, timing, and more. 
  • Super fast. Faster than hand-written code. 
  • Super customizable. Override every single moving part. 
  • Works with your existing logging framework. 

 

PostSharp MVVM: the must-have companion for your XAML developments 

Stop writing repeating code for: 

  • INotifyPropertyChanged, 
  • Commands, 
  • Dependency Properties, 
  • Code Contracts, 
  • Undo/Redo, 
  • Weak Events, 
  • Parent/Child Relationships and Visitors 

 

PostSharp Threading: the pragmatic way to write verifiably thread-safe code 

Address multithreading at the right level of abstraction with threading models,
deadlock detection, and more. 

Starting new threads and tasks in .NET languages is simple, but ensuring that objects are thread-safe is not. Choose the threading models that you want and have the built-in verification detect errors in your code before they cause random data races. 

  • Decrease complexity caused by threading. 
  • Get deterministic errors instead of random data races. 
  • Detect and diagnose deadlocks. 

 

PostSharp Caching: the straightforward way o improve performance 

Add caching to an existing method with just a custom attribute. Works with Redis, MemoryCache, and your custom cache framework. 

  • Declarative caching and cache invalidation – using compiler-verified custom attributes. 
  • Out-of-the-box support for MemoryCache and Redis. 
  • Object-oriented dependencies for strongly-typed cache invalidation. 
  • Customizable. Plug into your own cache storage. 
  • Support for async methods and async cache storages. 

Using PostSharp on a Build Server 

PostSharp has been designed for frictionless use on build servers. PostSharp build-time components are deployed as NuGet packages, and are integrated with MSBuild. No component needs to be installed or configured on the build server, and no extra build step is necessary. If you choose not to check in NuGet packages in your source control, r 

Installing a License on the Build Server 

There are several ways to install a license on the build server: 

  • Don’t install it. It is not necessary to install the license key on the build server unless you are using the features of PostSharp Logging. 
  • Add your license key to the postsharp.config file and add this file to the source 
  • Set an environment variable named PostSharpLicense to a semicolon-separated list of your license keys. 

We do not recommend to install the license key on a build server using the user interface. 

PostSharp started as an open-source project in 2004 and due to its popularity, it soon became a commercial product trusted by over 50,000 developers worldwide and over 1,000 leading corporations. More than 10% of all Fortune 500 companies including Microsoft, Intel, Bank of America, Phillips, NetApp, BP, Comcast, Volkswagen, Hitachi, Deutsche Bank, Bosch, Siemens, and Oracle rely on PostSharp to reduce their development and maintenance costs.

In PostSharp 6.6 we’re introducing Per-Repo Subscriptions, a pricing model where you are not charged per daily unique active user but per amount of source code in which you use PostSharp.

With Per-Repo Subscriptions, we’re hoping to lower the barrier to entry for large teams that want to get started with PostSharp without paying a full license fee for all developers.

The price of Per-Repo Subscriptions starts at $250 for PostSharp Ultimate or $50 for PostSharp Logging.

What’s so bad about per-user licensing:

Software development tools have traditionally been priced per user. If your team of 20 uses Visual Studio, you need to purchase 20 licenses. Per-user pricing is simple to explain and enforce. No wonder it has become the de-facto standard in the software development tools industry. It makes sense for an IDE because most developers open it every day. The ROI of Visual Studio would be much smaller for developers who open the IDE once per week, but this would not be a typical situation.

However, not all software development tools have the same economics as an IDE. How do you price, say, a data grid control? Suppose you have 10 devs working on a project and you need one data grid. One developer adds the data grid to the app and spends one week integrating it in the codebase. After the initial developer merges the changes, the whole team will need to be able to build the code. With a per-user pricing model, all 10 developers need to be licensed – for a single instance of the control. This cost is clearly prohibitive.

The caveats of per-user licensing explain many things in our industry: why UI component vendors try to sell large bundles instead of single controls, but also why customers turn to lower-quality open-source products.

(Note for those interested in economics theory. The per-user pricing model does not lead to Pareto-efficient markets because the product price for the customer is not proportional to its utility. Both the buyer and the seller would have interest in doing more business together – the reason of the market inefficiency is not the product, but the pricing model itself.)

Enter per-repo subscriptions

So, how to make the cost of PostSharp more proportional to its usefulness? One of the most important metrics of utility of PostSharp is how much boilerplate code you avoid writing thanks to it. This metric cannot be estimated with enough precision to serve as a pricing basis, so it is not a good candidate. However, the amount of boilerplate code you save is proportional to the amount of hand-written code to which you apply aspects, and this metric can be reliably and precisely measured.

That’s why we chose to base our new pricing model on the number of lines of code that you enhance with PostSharp.

All developers would agree that counting lines of code is not the panacea. It is a metric, one that’s reasonably simple to measure and one that is proportional to the benefit you get from using PostSharp. It’s a compromise, and we hope that for many customers it’s a better one than counting unique daily active users.

Because this new type of subscription is bound to a specific code base, we require the license key to be checked in your source code repository (in a file named postsharp.config). Anybody cloning and building that code would automatically use this subscription. This is why we call it the Per-Repo Subscription.

How do we count lines of code?

There is no industry standard about counting source lines of code (SLOC). Different tools would report very different results. What’s important is to only compare numbers given by the same algorithm.

We chose a counting method that does not depend on code formatting and the amount of blank lines and comments. This method is very fast and precise enough. We count:

  • one line for each declaration (i.e. for each class, struct, delegate, enum, property, property accessor, event, event accessor, method, field)
  • one line for each debugger sequence point (i.e. each unique source code location where a breakpoint can be enabled), as emitted by the C# compiler, minus two for the opening and closing bracket

We do not count lines of code for: namespaces, generic parameters, or custom attributes.

The granularity level is the class or the struct. If you apply an aspect to a single method of a type, we will count all lines of this type. This, again, is a technical compromise of simplicity and performance, and we understand it may be considered as “unfair” in some situations.

Aggregating lines of code in the cloud

Since the license key of the subscription is stored in your source code repository, and since different developers may work on different subsets of the code base, how do we ensure that developers together do not exceed the number of SLOC?

Short answer: we count on each device, upload anonymized metrics to the cloud, then aggregate per subscription. Daily.

For each C# project, on each device, we compute the number of enhanced lines of code once per day. We create a file, for each project, mapping a non-reversible hash of the type name to the number of lines of code in this type. Then, each day and on each device, we aggregate yesterday’s files for all projects, and upload the aggregate to the cloud. The data ends up in Data Lake Analytics.

If you are not online every day, it does not matter – but we do require an internet connection once per week for this licensing model.

Then, once per day, we run a Data Lake Analytics job to aggregate data per subscription. We prepare detailed reports to be displayed in the customer portal, which looks like this:

 

Additionally, the script exports summaries for our sales teams. When we notice that the consumption is higher than the entitlements, we will try to contact you and ask you to purchase more.

We trust you by default. We will not break your build before we contact you. If you fail to increase the size of your subscription, we reserve the right to remotely deactivate your subscription.

Per-Repo Subscriptions are Transferable

Consultancies and bespoke development shops will appreciate this: once your project ends, you can transfer the licenses to your customer together with your source code. Seems logical since the license key is in the source repository, doesn’t it? A legal note: there’s an additional form that the three parties need to sign to make the transfer legally effective.

Example

Say you have a team of 100 developers and a code base of 1,000,000 lines of code (1,000 KSLOC): a large system with server, desktop and mobile apps.

You’ve just discovered our [NotifyPropertyChanged] aspect and think you could reduce boilerplate on your MVVM classes. The per-user price for 100 devs would get you to a 5-digit price: a no-starter for your development director. You estimate that you will need to add 10 KLOC of MVVM code in the next months, so all you need to get started is a PostSharp Ultimate Per Repo license for 10 KSLOC. Since 1 KSLOC is given for free, your entry price is 9 x $250 = $2,250. This is just 22$ per developer! Now your development director wishes all publishers would propose our licensing model.

After your first experience with PostSharp, you learn about other aspects such as caching or authentication, and you start adding them to your server-side code. As your usage of PostSharp increases, you increase the size of your subscription. Eventually, you may decide that switching to a per-user subscription is best for you. But from the beginning, you’ve enjoyed a maximal return on investment.

Deploying PostSharp to End-User Devices:

Although PostSharp is principally a compiler technology, it contains run-time libraries that need to be deployed along with your application to end-user devices.

This topic contains the following sections:

  • Redistribution of PostSharp run-time libraries without NuGet
  • Redistribution of PostSharp run-time libraries using NuGet
Redistribution of PostSharp run-time libraries without NuGet

If you do not deliver your final product using NuGet, you can bundle all the referenced PostSharp run-time libraries in your product. These libraries are the ones included in the lib subdirectory of the NuGet packages and the ZIP distribution.

These run-time libraries can be distributed to end-users free of charge. However, the build-time parts of PostSharp cannot be redistributed under the terms of the standard license agreement.

Besides including these run-time libraries, no other action or configuration is required.

Redistribution of PostSharp run-time libraries using NuGet

If you deliver your final product using NuGet, you can add PostSharp redistributable NuGet packages as a dependency to your NuGet package instead of including all the run-time libraries inside your NuGet package.

PostSharp NuGet packages are either intended for build-time or for run-time. We do not mix both in any of our NuGet packages. See PostSharp Components for a description of how to distinguish them.

Thanks to this fact, you only need to set the run-time PostSharp NuGet packages as a dependency of your NuGet package.

Sample NuGet package

In the following example, there is a NuGet package specification of a package which has the PostSharp.Redist package as its dependency. This way, there’s no need to include the PostSharp run-time libraries inside the package.

XML
<?xml version="1.0" encoding="utf-8"?>
<package xmlns="http://schemas.microsoft.com/packaging/2013/05/nuspec.xsd">
  <metadata>
    <id>MyLibrary</id>
    <version>1.0.0</version>
    <authors>John Smith</authors>
    <owners>John Smith</owners>
    <requireLicenseAcceptance>false</requireLicenseAcceptance>
    <description>This is my library created with a help of PostSharp.</description>
    <dependencies>
      <!-- TODO: Replace X.X.X with a version of PostSharp you want to be dependent. -->
      <dependency id="PostSharp.Redist" version="X.X.X" />
    </dependencies>
  </metadata>
  <files>
    <file src="bin\Release\MyLibrary.dll" target="lib\net46"/>
    <!-- NOTE: No need to include PostSharp run-time libraries inside the package. -->
  </files>
</package>

See .nuspec reference for details.

Using the Pack MSBuid target or .NET Core CLI

In the following example, you see a .NET Core project which uses the PackageReference package management format. Creating a NuGet package using the Pack MSBuid target or .NET Core CLI command dotnet pack from this project will create a NuGet package which will depend on the run-time PostSharp packages only.

XML
<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp1.1</TargetFramework>
  </PropertyGroup>

  <ItemGroup>

    <!-- TODO: Replace X.X.X with a version of PostSharp you want to be dependent. -->
    <PackageReference Include="PostSharp" Version="X.X.X">
      <!-- NOTE: Thanks to the following element, the PostSharp build-time NuGet package
                 will not be a dependency of the NuGet package created from this project. -->
      <PrivateAssets>All</PrivateAssets>
    </PackageReference>

    <!-- TODO: Replace X.X.X with a version of PostSharp you want to be dependent. -->
    <PackageReference Include="PostSharp.Redist" Version="X.X.X" />
    <!-- NOTE: The PostSharp.Redist run-time NuGet package
               will be a dependency of the NuGet package created from this project. -->

  </ItemGroup>

</Project>

Features

Major Features of PostSharp:

  • INotifyPropertyChanged: Eliminate the INotifyPropertyChanged boilerplate and focus on business.
    Massive code reduction.
    Consistent and reliable implementation.
    Customizable to your needs.

<strong>INotifyPropertyChanged</strong><br /><br />

  • Undo/Redo:Give your users the familiar Undo/Redo experience without breaking the bank.
    Undo/Redo any object state change.
    Handle multiple changes as one step.
    Works consistently on fields, properties or parameters.
    Rich built-in contracts.

<strong>Undo/Redo</strong><br /><br />

  • Extensible  Logging: Add comprehensive logging to your app without impact on source code.
    Super easy. You’ll be done in minutes.
    Multi-Framework Support
    High Performance.

<strong>Logging</strong><br /><br />

 

Thread Safety

Make your C# or VB applications thread-safe without rewriting them.

  • Decreased Complexity.
  • Faster feedback.
  • Take control.
Aspect-Oriented Programming

Videos

 

Aspect Oriented Programming with PostSharp

Example of using PostSharp in a WPF app

PostSharp on cloud

Related Posts