Open sandboxFocusImprove this doc

PS0165: Type in a Configuration File Has No Parameterless Constructor

Severity Error
Reported by PostSharp
Message The type '<ElementName>' does not have a default constructor.

Cause

In some sections of a PostSharp configuration file, such as the Multicast section and the logging profiles, each XML element describes a CLR object. PostSharp creates the object with the constructor of the type that has no parameters, then sets its fields and properties from the XML attributes of the element. Unlike a custom attribute in C#, an XML element cannot pass constructor arguments.

PostSharp reports PS0165 when the type has no constructor without parameters, and ignores the element. <ElementName> is the local name of the XML element, which can omit the Attribute suffix of the type name.

In the following example, the only constructor of the LogAttribute aspect takes the category as a parameter.

<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.postsharp.org/1.0/configuration">
  <Multicast xmlns:app="clr-namespace:Errors.PS0165_Error;assembly:PS0165_Error">
    <!-- LogAttribute has no parameterless constructor, so this element cannot create it. -->
    <app:LogAttribute AttributeTargetTypes="Errors.PS0165_Error.OrderService" AttributeTargetMembers="PlaceOrder" Category="Orders" />
  </Multicast>
</Project>
using System;
using PostSharp.Aspects;
using PostSharp.Serialization;

namespace Errors.PS0165_Error;

[PSerializable]
public class LogAttribute : OnMethodBoundaryAspect
{
    // The only constructor of the aspect has a parameter.
    public LogAttribute( string category )
    {
        this.Category = category;
    }

    public string Category { get; set; } = "General";

    public override void OnEntry( MethodExecutionArgs args )
    {
        Console.WriteLine( $"[{this.Category}] Entering {args.Method.Name}." );
    }
}

public class OrderService
{
    // The Multicast element of postsharp.config applies [Log] to this method.
    public void PlaceOrder( string product )
    {
        Console.WriteLine( $"Order placed for {product}." );
    }
}

public static class Program
{
    public static void Main()
    {
        new OrderService().PlaceOrder( "Coffee" );
    }
}
error PS0165: postsharp.config(5,6): The type 'LogAttribute' does not have a default constructor.

Resolution

Add a parameterless constructor to the type, and expose each value that a constructor parameter receives as a public property or field, which the XML element can set as an attribute. You can keep the other constructors for the code that uses the type as a custom attribute.

In the following example, the aspect has a parameterless constructor, and the element sets the Category property.

<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.postsharp.org/1.0/configuration">
  <Multicast xmlns:app="clr-namespace:Errors.PS0165_Fixed;assembly:PS0165_Fixed">
    <!-- LogAttribute has a parameterless constructor, and the element sets Category as a property. -->
    <app:LogAttribute AttributeTargetTypes="Errors.PS0165_Fixed.OrderService" AttributeTargetMembers="PlaceOrder" Category="Orders" />
  </Multicast>
</Project>
using System;
using PostSharp.Aspects;
using PostSharp.Serialization;

namespace Errors.PS0165_Fixed;

[PSerializable]
public class LogAttribute : OnMethodBoundaryAspect
{
    // The aspect has a parameterless constructor.
    public LogAttribute()
    {
    }

    public string Category { get; set; } = "General";

    public override void OnEntry( MethodExecutionArgs args )
    {
        Console.WriteLine( $"[{this.Category}] Entering {args.Method.Name}." );
    }
}

public class OrderService
{
    // The Multicast element of postsharp.config applies [Log] to this method.
    public void PlaceOrder( string product )
    {
        Console.WriteLine( $"Order placed for {product}." );
    }
}

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

See Also

Other Resources

Including CLR Objects in Configuration
Adding Aspects Using XML