Open sandboxFocusImprove this doc

LA0035: Non-Serialized Aspect Provided as an Instance

Severity Error
Reported by PostSharp
Message The aspect <Aspect> has no serializer, but it has been provided to <Target> as an instance. An aspect that is not serialized must be provided as an ObjectConstruction.

Cause

PostSharp creates aspects at build time and must recreate them at run time. By default, it serializes the build-time instance and deserializes it at run time. An aspect whose serializer is MsilAspectSerializer is not serialized: PostSharp emits code that calls its constructor and sets its fields and properties, from the custom attribute or the ObjectConstruction that describes it.

An aspect that implements IAspectProvider can provide another aspect in two ways: as an instance, with the constructor of AspectInstance that takes an IAspect, or as a construction, with the constructor that takes an ObjectConstruction. An instance carries no description of how to construct it, so PostSharp can only serialize it. When the provided aspect is not serialized and is provided as an instance, PostSharp reports LA0035 on the aspect class.

In the following example, [Trace] uses MsilAspectSerializer, and [TraceMethods] provides it to the methods of OrderService as instances.

using System;
using System.Collections.Generic;
using System.Reflection;
using PostSharp.Aspects;
using PostSharp.Aspects.Configuration;
using PostSharp.Aspects.Serialization;
using PostSharp.Reflection;
using PostSharp.Serialization;

namespace Errors.LA0035_Error;

// The aspect is not serialized: PostSharp creates it at run time from its constructor.
[OnMethodBoundaryAspectConfiguration( SerializerType = typeof(MsilAspectSerializer) )]
public class TraceAttribute : OnMethodBoundaryAspect
{
    public override void OnEntry( MethodExecutionArgs args ) => Console.WriteLine( $"Entering {args.Method.Name}." );
}

[PSerializable]
public class TraceMethodsAttribute : TypeLevelAspect, IAspectProvider
{
    public IEnumerable<AspectInstance> ProvideAspects( object targetElement )
    {
        var type = (Type) targetElement;

        foreach ( MethodInfo method in type.GetMethods( BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly ) )
        {
            // The aspect is provided as an instance, which PostSharp cannot serialize.
            yield return new AspectInstance( method, new TraceAttribute() );
        }
    }
}

[TraceMethods]
public class OrderService
{
    public void PlaceOrder( string product ) => Console.WriteLine( $"Order placed for {product}." );
}

public static class Program
{
    public static void Main()
    {
        new OrderService().PlaceOrder( "Book" );
    }
}
error LA0035: LA0035_Error.cs(14,14): The aspect Errors.LA0035_Error.TraceAttribute has no serializer, but it has been provided to Errors.LA0035_Error.OrderService.PlaceOrder(System.String) as an instance. An aspect that is not serialized must be provided as an ObjectConstruction.

Resolution

Choose one of these fixes:

In the following example, [TraceMethods] provides the aspect as an ObjectConstruction.

using System;
using System.Collections.Generic;
using System.Reflection;
using PostSharp.Aspects;
using PostSharp.Aspects.Configuration;
using PostSharp.Aspects.Serialization;
using PostSharp.Reflection;
using PostSharp.Serialization;

namespace Errors.LA0035_Fixed;

// The aspect is not serialized: PostSharp creates it at run time from its constructor.
[OnMethodBoundaryAspectConfiguration( SerializerType = typeof(MsilAspectSerializer) )]
public class TraceAttribute : OnMethodBoundaryAspect
{
    public override void OnEntry( MethodExecutionArgs args ) => Console.WriteLine( $"Entering {args.Method.Name}." );
}

[PSerializable]
public class TraceMethodsAttribute : TypeLevelAspect, IAspectProvider
{
    public IEnumerable<AspectInstance> ProvideAspects( object targetElement )
    {
        var type = (Type) targetElement;

        foreach ( MethodInfo method in type.GetMethods( BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly ) )
        {
            // The aspect is provided as a construction, which PostSharp emits as a constructor call.
            yield return new AspectInstance( method, new ObjectConstruction( typeof(TraceAttribute) ) );
        }
    }
}

[TraceMethods]
public class OrderService
{
    public void PlaceOrder( string product ) => Console.WriteLine( $"Order placed for {product}." );
}

public static class Program
{
    public static void Main()
    {
        new OrderService().PlaceOrder( "Book" );
    }
}
Entering PlaceOrder.
Order placed for Book.

See Also

Reference

AspectInstance
ObjectConstruction
MsilAspectSerializer

Other Resources

Understanding Aspect Serialization
Adding Aspects Dynamically