Open sandboxFocusImprove this doc

PS0168: Member of an Unsupported Type Set in XML

Severity Error
Reported by PostSharp
Message The type '<MemberType>' of member '<Element>.<Member>' cannot be set in an XML configuration file. Use a field or property of an intrinsic type, an enumeration, System.Type, or an array of these types.

Cause

The Multicast element of a postsharp.config file adds aspects or other multicast attributes to the project without changing its source code, as Adding Aspects Using XML describes. Each XML attribute of a child element sets the public field or property of the same name of the attribute class.

PostSharp can convert the text of an XML attribute only into the following types: the intrinsic types (bool, char, the integer and floating-point types, and string), enumerations, Type, and arrays of these types. PostSharp reports PS0168 when the XML attribute sets a field or property of another type, for example TimeSpan, DateTime, Guid, decimal or object. <Element> is the local name of the XML element, and <Member> is the name of the XML attribute. The location of the message is the XML attribute in the postsharp.config file.

In the following example, postsharp.config sets the Threshold property of the [WarnIfSlow] aspect, which is a TimeSpan.

<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.postsharp.org/1.0/configuration">
  <Multicast xmlns:my="clr-namespace:Errors.PS0168_Error;assembly:PS0168_Error">
    <!-- The Threshold property is a TimeSpan. -->
    <my:WarnIfSlowAttribute AttributeTargetTypes="Errors.PS0168_Error.OrderService" AttributeTargetMembers="PlaceOrder" Threshold="00:00:00.500" />
  </Multicast>
</Project>
using System;
using System.Diagnostics;
using PostSharp.Aspects;
using PostSharp.Serialization;

namespace Errors.PS0168_Error;

// postsharp.config applies this aspect to OrderService.PlaceOrder and sets its Threshold property.
[PSerializable]
public class WarnIfSlowAttribute : OnMethodBoundaryAspect
{
    // A TimeSpan property cannot be set in postsharp.config.
    public TimeSpan Threshold { get; set; } = TimeSpan.FromSeconds( 1 );

    public override void OnEntry( MethodExecutionArgs args )
    {
        Console.WriteLine( $"Timing {args.Method.Name} against a threshold of {this.Threshold.TotalMilliseconds} ms." );
        args.MethodExecutionTag = Stopwatch.StartNew();
    }

    public override void OnExit( MethodExecutionArgs args )
    {
        Stopwatch stopwatch = (Stopwatch) args.MethodExecutionTag;

        if ( stopwatch.Elapsed > this.Threshold )
        {
            Console.WriteLine( $"Warning: {args.Method.Name} took {stopwatch.ElapsedMilliseconds} ms." );
        }
    }
}

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( "Coffee" );
    }
}
error PS0168: postsharp.config(5,121): The type 'System.TimeSpan' of member 'WarnIfSlowAttribute.Threshold' cannot be set in an XML configuration file. Use a field or property of an intrinsic type, an enumeration, System.Type, or an array of these types.

Resolution

  • Replace the member by one of a supported type, and convert its value in the aspect: for example, an int number of milliseconds instead of a TimeSpan, or a string that the aspect parses.
  • Set the member in code instead, where the attribute is applied with C#, or initialize it in the aspect.

The formats of the supported types are described in Including CLR Objects in Configuration.

In the following example, the aspect has a ThresholdMilliseconds property of type int, which postsharp.config sets.

<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.postsharp.org/1.0/configuration">
  <Multicast xmlns:my="clr-namespace:Errors.PS0168_Fixed;assembly:PS0168_Fixed">
    <!-- The ThresholdMilliseconds property is an int. -->
    <my:WarnIfSlowAttribute AttributeTargetTypes="Errors.PS0168_Fixed.OrderService" AttributeTargetMembers="PlaceOrder" ThresholdMilliseconds="500" />
  </Multicast>
</Project>
using System;
using System.Diagnostics;
using PostSharp.Aspects;
using PostSharp.Serialization;

namespace Errors.PS0168_Fixed;

// postsharp.config applies this aspect to OrderService.PlaceOrder and sets its ThresholdMilliseconds property.
[PSerializable]
public class WarnIfSlowAttribute : OnMethodBoundaryAspect
{
    // An int property can be set in postsharp.config.
    public int ThresholdMilliseconds { get; set; } = 1000;

    public override void OnEntry( MethodExecutionArgs args )
    {
        Console.WriteLine( $"Timing {args.Method.Name} against a threshold of {this.ThresholdMilliseconds} ms." );
        args.MethodExecutionTag = Stopwatch.StartNew();
    }

    public override void OnExit( MethodExecutionArgs args )
    {
        Stopwatch stopwatch = (Stopwatch) args.MethodExecutionTag;

        if ( stopwatch.ElapsedMilliseconds > this.ThresholdMilliseconds )
        {
            Console.WriteLine( $"Warning: {args.Method.Name} took {stopwatch.ElapsedMilliseconds} ms." );
        }
    }
}

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( "Coffee" );
    }
}
Timing PlaceOrder against a threshold of 500 ms.
Order placed for Coffee.

See Also

Other Resources

Adding Aspects Using XML
Including CLR Objects in Configuration
Configuring Projects Using postsharp.config