Search code examples
c#postsharp

How to define invariant and postconditions using PostSharp?


I have found in the PostSharp documentation a topic about contracts. As I understood that feature allows only to check input and output parameters throught aspects. But I didn't find anything about class invariants and postconditions. Before I tried to use C# Code Contracts but .Net Core doesn't support that thing. Now I want to try to use OnMethodBoundaryAspect from PostSharp for the checking invariants, preconditions and postconditions. What is the best way to do it if I use PostSharp? Do exist other tools for contract programming? The main reason of the usage of tools is that I don't want bound a main code with the contract checks.


Solution

  • There is a nice example for class invariants in this blog post: https://www.postsharp.net/blog/post/inheritance-of-aspects-in-postsharp-1-5-ctp-2

    Basically, you create an interface with a method(s) to check the invariants, you create an OnMethodBoundary aspect which makes all public method in the target type to call the methods from the interface before and/or after the method calls and you apply the aspect on the interface. You also set the aspect to be inherited to all types which implement the interface. (See the blog post for a detailed explanation.)

    This way, by implementing the interface in a class, you automatically get the pre and post conditions checked.

    The code of the interface and the aspect can look like this, as seen in the blog post:

    [ConsistantAspect]
    public interface IConsistant
    {
        void CheckConsistency();
    }
    
    [AttributeUsage(AttributeTargets.Interface)]
    [MulticastAttributeUsage(
        MulticastTargets.Method,
        TargetMemberAttributes =
     MulticastAttributes.Public
     | MulticastAttributes.Protected
     | MulticastAttributes.Internal
     | MulticastAttributes.Instance,
        Inheritance = MulticastInheritance.Multicast)]
    [Serializable]
    public sealed class ConsistantAspect : OnMethodBoundaryAspect
    {
        public override void OnSuccess(MethodExecutionEventArgs eventArgs)
        {
            ((IConsistant) eventArgs.Instance).CheckConsistency();
        }
    }
    

    Edit: With CompileTimeValidate method, you could do some validation in build time and reduce the runtime overhead of the validation. See https://doc.postsharp.net/m_postsharp_aspects_aspect_compiletimevalidate_368fa5ad.