Archive

This is a guest post by Alessandro Federici. Alessandro is a System Architect at CODY Systems, an industry leader in the collection, analysis, and sharing of critical data for public safety, law enforcement, and intelligence agencies in the United States for over 30 years. CODY Systems specializes in integrated public safety software solutions and interoperable vendor-neutral information-sharing for First Preventers.

Occasionally we’re asked by teams that are evaluating PostSharp to provide examples of organizations using it in real-world scenarios. I understand the request completely. It’s one thing for teams to try a new product that’s backed by loads of documentation and tutorials, but learning how companies from a variety of different industries are using it to successfully produce cleaner, more efficient, code builds trust in a way no other document can.

In the past, we’ve pointed to success stories such as FullArmor, Siemens Audiology, Thales Information Systems and IdeaBlade. In today’s post, Alessandro shows how he and his team at CODY are using PostSharp in a variety of ways to reduce code clutter, handle errors, simplify what they write and make their code more readable.

Enter Alessandro

My interest in Aspect Oriented Programming (AOP) started in 2005, approximately. At the time I was working at RemObjects Software (I was one of the two founders) and we had recently started the development of our compiler. The engineers behind it planned to natively support AOP. I didn't know anything about aspects at the time, but the moment I saw and had a chance to use them I got hooked and I realized their elegance and power. In a way, I think I had the classic "how could I live without them?" moment where you lean back on your chair, stair at the monitor and question decades of your (programming) life.

Years then passed. I left RemObjects Software and I am now System Architect for CODY Systems where we develop applications using exclusively C#. As a Delphi/Oxygene old-timer, I had my moments with C# but I came to love it. Yet, the lack of native AOP features has always bothered me. To use a parallel example, adopting aspects feels like adopting lambda expressions and Where() calls: Once you start using them there's no going back to for-i loops that embed if statements. It gets you to the same end-result, but it just feels and reads sloppy, to me.

A client-tier rid of unnecessary code

CODY is currently working on major enhancements of the infrastructure and picked some of the best-of-breed tools for .NET. PostSharp is definitely one of them and will play a large role in our re-factoring and re-engineering efforts.

Our system is built off of different modules and follows some of the common multi-tier design patterns. We have a client tier, an application-server tier and a data-storage tier. The client-tier is made off of different client applications: Some are written using WPF, one is in Silverlight and others use MVC, depending on the need.

Our WPF and Silverlight clients are all built using the MVVM pattern where the INotifyPropertyChanged interface plays a fundamental role. This is the first place where PostSharp will greatly help us re-factoring leaner and cleaner code. Currently we have hundreds of properties that explicitly fire notification events with code such as this:

public string FirstName
{
    get { return _firstName; }
    set { ChangeAndNotify(value, ref _firstName, () => this.FirstName); }
}

We have put effort into alleviating the most common problem with INotifyPropertyChanged: We don't use error-prone, "magic" strings to reference property names and we have code snippets that help writing that code. Still, in the end, we continue to have hundreds of lines of code that have nothing to do with business logic and only exist to address what is, in most cases, just a user interface concern.

Thanks to PostSharp, all that baggage will go away and we will be able to use automatic properties where possible and concentrate on the business logic associated to the property.

The code above can now turn into the following:

[NotifyAspect]
[CapitalizeNameAspect]
[StringLength(1, 100)]
public string FirstName { get; set; }

 

This new code (which is also one line shorter) does everything the previous one was doing but also adds two new extra “business” operations. It's more readable and directly communicates the intent behind FirstName.

I also compared the amount of bytes the old code and new code took on disk: The new code is less than half of what it used to be. I could also give the new code to non-developers who would have a chance to understand what they got, finally!

But there's more we can do, thanks to the fact PostSharp aspects are implemented through attributes.

Self-documenting validation aspects for a discoverable and rock-solid server-tier

One of the modules of our system generates HTML documentation by using reflection. Any time we add a new domain object, new documentation pages get dynamically generated and provide an English description of all its properties, along with their constraints and other useful information. The data annotation StringLength displays as “The length of FirstName must be between 1 and 100”. CapitalizeAspect displays as “The value assigned to this property will be automatically capitalized”. NotifyAspect only displays when it's not attached to a property, as a reminder of a special case.

In other words, aspects allowed us to first add and later infer behavior through the use of simple attributes. All that without having to maintain two separate documents containing such information: the code and manual text just for help files.

This feature is critical for our application server tier. CODY's application server has been openly accessible for years, through simple HTTP calls and XML messages. It's a very important part of our infrastructure for many different reasons. The features we are now adding make this tier much easier to understand, use and test and the self-documenting aspect is of paramount importance in all this.

This brings us to the next use of PostSharp: ServiceMessageHandlerAspect. Our API layer is composed of services whose methods receive one request and return one or more responses. For instance, our sample CalculatorService is coded as:

[Description("Performs simple mathematical calculations")]
public sealed class CalculatorService
{
    [...]
   
    [ServiceMessageHandlerAspect]
    [Description("Sums two integer numbers")]
    public SumResponse Sum(SumRequest request)
    {         
        return new SumResponse()
        {
            Result = request.A + request.B
        };            
    }        
}

SumRequest is coded as:

[Description("A message that contains two operands (A and B) for a sum operation.")]
public class SumRequest : ServiceRequest
{
    [...]

    [Required]
    [Range(0, 1000000)]
    [Description("Number A")]
    public int? A { get; set; }

    [Required]
    [Range(0, 1000000)]
    [Description("Number B")]
    public int? B { get; set; }
}

 

The implementation of CalculatorService.Sum() only returns a result with the sum of A and B, but ServiceMessageHandlerAspect does a lot more for us, behind the scenes. When this aspect is applied to a method, validation code ensures that all the data annotations bound to SumRequest are satisfied (e.g. A and B are not null and their values are between 0 and 100000) before letting the flow get into the Sum() implementation. If any requirements are not met, the execution of Sum() is skipped and a SumResponse containing error information is returned to the caller.

In other words, by using this aspect and by defining solid request classes with validation attributes, we can be sure that whenever our service methods are called, their request argument is well formed and contains everything that is needed for it to be processed.

Among the same lines, responses can also contain validation attributes. ServiceMessageHandlerAspect ensures that whatever output is generated by the method matches such requirements.

Uniform and standardized access to 3rd party products through exception wrapping

Finally, we have another aspect that greatly helps us in error management: The WrapExceptionsAspect.

Like I mentioned before, we picked a number of the best-of-breed tools for the development of our core. We have queuing and caching integrated in the core, for scalability purposes. While these products are very solid and unlikely to disappear from the market, we abstract them and access them only through interfaces. What we cannot abstract easily are the errors these products return. Some might have their own exception types while others might use standard .NET Exception classes. What we wanted, in our wrappers, is to be sure that whenever an error occurs in the current cache implementation, we always get back a CacheException (which then embeds the original exception).

The following code shows how we use the WrapExceptionsAspect:

public abstract class BaseCache : BaseDisposable, ICache
{
   [..] 
    [WrapExceptionsAspect(typeof(CacheException), null)]
    void ICache.Store(string key, object value, int? maxMinutes)
    {
        if (!InternalStore(key, value, maxMinutes))
            throw new CacheException(string.Format("Cannot store item [{0}] in the cache", key));            
    }
   [..] 
    [WrapExceptionsAspect(typeof(CacheException), null)]
    bool ICache.TryGet(string key, out T value, int? maxMinutes)
    {
        return InternalTryGet(key, out value, maxMinutes);            
    }
    [..] 
}

 

The above could have been easily accomplished by using a try...catch block around the calls to the Internalxxx methods but that would have meant having that extra code in each of the methods above and in any of the other wrapper classes we have (e.g. Queuing, etc.).

If we were to change how exception interception worked we would have had to touch every method. With the aspect we built we can be sure that there's one place to touch and all our wrappers immediately change.

Conclusion

Any piece of code that performs a function can be written in infinite ways. Many of such implementations will work and will produce the same results, but I strongly believe the result is not all that matters. How you achieve your goal is, many times, just as important. If a certain implementation is hard to read, understand or modify, it will cause problems down the road. Using aspects helps reducing clutter in code. It helps simplifying what we write and, later, what we read. It's a very elegant, simple and effective way to write code that focuses on the real problem, not language or framework needs.

Join us on Thursday, September 13th, for the next PostSharp Live Webinar when our guest will be Karol Waledzik from Internetium.


Karol WaledzikKarol is the software architect and team lead at Internetium in Warsaw, Poland, and is largely responsible for building our new line of PostSharp Toolkits.

He wrote a 2-part blog post last month about the pain most WPF developers experience by having to manually implement change notifications, and how the Domain Toolkit, the latest addition to our product family, automates this for (nearly) all standard business cases.

On Thursday’s live webinar, Karol will walk you through the PostSharp Domain Toolkit and show how it treats the implementation of INotifyPropertyChanged seriously and finally ends change notifications pain for WPF developers.

 

During the webinar you will learn:

  • Why previous attempts to tackle INotifyPropertyChanged by other libraries fell short
  • What makes the Domain Toolkit different from other libraries
  • How the toolkit automates change notifications
  • What other scenarios the toolkit supports automatically
  • The limitations of the toolkit and available customization

If you're tired of having to manually implement INotifyPropertyChanged in WPF applications, and want to gain insight into how the PostSharp Domain Toolkit can end change notification pain in your own projects, be sure to watch Thursday's live webinar.

Space is limited.

Reserve your Webinar Seat Now >>

Continuing from the previous post on INotifyPropertyChanged and the PostSharp Domain Toolkit, it’s now time to satisfy curiosities and share some details on how the framework works, what its limitations are and how to overcome them by using available customization.

What the Domain Toolkit Does

If you looked closely at the sample classes in the previous blog post, you probably noticed they did not actually implement INotifyPropertyChanged interface, yet WPF still received the notifications.

How is that possible?

Our NotifyPropertyChangedAttribute simply introduces the interface during compilation. This is a very convenient approach in many cases, especially if you don’t need to listen for the notifications yourself.

In cases where you want to implement the interface explicitly or inherit from a class that already has the interface, the toolkit will expect you to implement an OnPropertyChanged(string) method raising the PropertyChanged event, because it’s impossible in .NET world to externally raise an object’s event.

[NotifyPropertyChanged]
class Entity : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    protected void OnPropertyChanged( string propertyName )
    {
	PropertyChangedEventHandler handler = this.PropertyChanged;
        if ( handler != null )
            handler( this, new PropertyChangedEventArgs( propertyName ) );
    }

    //...
} 

When the Domain Toolkit Does It

In the previous post I mentioned that one of the features that distinguish our solution from the competition is the ability to automatically raise notifications only at the points in time in which objects are expected to be consistent.

Recall this snippet:

public class Account
{
    public decimal Balance { get; private set; }
    public DateTime LastOperationTime { get; private set; }
    public int RemainingDailyOperationsLimit { get; private set; }
 
    //...

    public void Withdraw(decimal amount)
    {
        //... all kinds of checks ...

        this.LastOperationTime = DateTime.UtcNow;
        this.RemainingDailyOperationsLimit--;
        this.Balance -= amount;
    }
 
    //...
}

Here you probably want to raise the change notifications when the full withdrawal operation has been completed and not after each property change. Our algorithm here assumes that whenever control returns from an object’s method to its caller in another object the executing instance (as well as all other objects modified by the method) should be in a consistent state. The toolkit at this point will raise notifications for all modified properties except those belonging to other objects currently higher in the stack trace (these objects may still be inconsistent).

Additionally, it tracks changes separately for each executing thread and always raises notifications on the thread whose actions resulted in the property value change.

How the Domain Toolkit Works

You may have figured out by now that our solution relies heavily on static compile-time analysis of the code of your property getters (and all other code they invoke directly or indirectly). This allows us to build a dependency map of all the fields and properties of the instrumented classes, which is then used during runtime for notifications generation.

Obviously, while this process is very powerful it also has its limitations. Since we perform static analysis only, there are some code constructs we cannot understand fully and automatically. We can still be ready to deal with some of those cases but from time to time we will need your help. Fortunately, we put strong emphasis on early detection of any and all unsupported scenarios and warn you about them with build-time errors (accompanied by advice on how to fix the problem).

Let’s have a look at exactly what is supported and what isn’t.

Automatically Supported Scenarios

As you have seen in the previous post, there is a good chance we can handle your full code base automatically. Here is a short summary of the scenarios we support:

  • Automatic properties:
public string FirstName { get; set; }
  • Field-backed properties:
private string lastName;

public string LastName
{
    get { return this.lastName; }
    set { this.lastName = value; }
}
  • Properties depending on multiple fields:
private string firstName;
private string lastName;

public string FullName
{
    get { return string.Join(" ", this.firstName, this.lastName); }
}
  • Properties depending on other properties of the same object:
public string FirstName { get; set; }
public string LastName { get; set; }

public string FullName
{
    get { return string.Join(" ", this.FirstName, this.LastName); }
}
  • Properties depending (directly or indirectly) on methods within the same class:
public string FullName { get { return this.GetFullName(); } }

public string GetFullName()
{
    return string.Join(" ", this.FirstName, this.LastName);
}
  • Properties depending on chains of invocations of properties of other instrumented classes:
public string CustomerCity
{
   get { return this.customer.Address.City; }
}
  • Properties depending on some well-known and static .NET framework methods with no hidden dependencies, as well as any void methods with no ref or out parameters:
public string GetFullName()
{
    return string.Join(" ", this.FirstName, this.LastName);
}
  • Any combination of the above cases, including recursive dependencies on properties and methods fulfilling above criteria

Limitations

You can probably use the above list to find the missing scenarios and work out library limitations but here’s a quick round-up of the most important ones in the current version of the framework:

  • Property getters depending on methods on other objects (except cases mentioned above)
  • Dependencies on external objects’ properties more complex than property getters invocation chains mentioned above
  • Properties depending on virtual methods
  • Direct or indirect usage of delegates in property getters
  • Dependencies on static fields
  • Properties depending on items in collections

As I mentioned before, all of these cases are detected at build-time and generate compile errors, at the same time advising you on possible workarounds.

The good news is we also provide you with a handy set of tools and APIs to effectively deal with the cases above if you should ever encounter them. Let’s have a look at them, starting with the simplest ones.

Manual Overrides

Should you decide you don’t need automatic change notifications for a single property in an otherwise instrumented class, be it the property never changes, or you know you’ll never bind to it, or that you simply want to raise the events manually, we provide you with that option. Simply mark the property with NotifyPropertyChangedIgnoreAttribute:

[NotifyPropertyChangedIgnore]
public string FullName { get { return this.GetFullName(); } }

If, in some scenarios, you feel that our toolkit plays it a bit too safe, e.g. reporting errors about unsupported code constructs in your property getter when in reality those non-analyzable snippets have no influence on the property value , you can ignore the errors by using NotifyPropertyChangedSafeAttribute:

[NotifyPropertyChangedSafe]
public string FullName
{
    get
    {
        this.logger.Log( "FullName property getter on {0}", this );
        return this.GetFullName();
    }
}

Let’s say you want to skip the analysis phase completely and simply define what your property depends on. Our framework supports dependencies on fields of the same class and properties of other instrumented classes. You can also construct dependencies as chains of such properties. All you need to do is put a snippet of code at the beginning of your property getter:

public string BusinessCard
{
    get
    {
       if (Depends.Guard)
       {
          Depends.On(this.FirstName, this.LastName,
                      customer.Address.Line1, customer.Address.Line2);
       }

       //…
    }
}

The Depends.Guard statement always evaluates to false, so that Depends.On() method is never actually executed and has no performance impact. We treat the necessity of using the if (Depends.Guard ) statement as a temporary solution and plan to get rid of it completely in a future release (allowing you to write single Depends.On() statements with no performance impact).

Still, the current syntax is already fully IntelliSense and refactoring friendly and these were our most important design goals for this iteration.

Idempotent Methods

In some cases you may know more about a method than our static analyzer can infer. You may know for instance that a particular method’s output value depends only on its arguments, or that any other dependencies it has can be safely treated as read-only. In such cases it’s not necessary for the toolkit to analyze the method nor does it matter if it violates some of the constraints.

We call such methods idempotent.

We introduced a special attribute called IdempotentMethodAttribute, which you can apply to a method to let the toolkit know that it can be safely ignored by the analyzer as long as only intrinsic types are passed as its arguments (in any other case the method’s return value could depend on arbitrary fields and properties of the passed objects).

That’s not to say that our library doesn’t know about some idempotent methods. If you have a look at the examples in this post and the previous one, you’ll notice that the toolkit automatically ignores calls to many .NET framework methods, such as string.Format(), string.Concat() or any usage of StringBuilder.

The algorithm assumes all static framework methods to be idempotent as long as only intrinsic type values are passed to them. Additionally, our solution also understands some of the often-used methods and classes, including the previously mentioned StringBuilder as well ToString() or GetHashCode().

Runtime Manipulations

Finally, for those of you who want to take full control and force the toolkit to raise events exactly when you need them, simply use static utility class NotifyPropertyChangedControllerand to perform one of several actions:

  • immediately raise events for all modified properties (except objects higher in the stack trace, which may be in an inconsistent state);
  • immediately raise events for all modified properties of a given object;
  • immediately raise notification for a specific property on a specific object (no matter whether the toolkit thinks it was modified or not).

Summary

All in all, our Domain Toolkit works “automagically” by default, giving you a INotifyPropertyChanged package that solves most of your needs, while also letting you take full control to tweak its behavior to meet all your needs. So grab the nuget package or download the source code from github, try it out and let us know what you think. We are, as always, open to your suggestions.

Happy PostSharping!

Karol Walędzik is an enterprise software applications architect and developer at Internetium Sp.z o.o. (Warsaw, Poland), as well as a .NET Programming and Artificial Intelligence lecturer and AI researcher at Warsaw University of Technology.