Open sandboxFocusImprove this doc

PS0263: Item Cannot Be Added to a Collection in a Configuration File

Severity Error
Reported by PostSharp
Message Cannot add <Item> to <Collection>: <Reason>

Cause

Some sections of a postsharp.config file, such as the Logging element, describe objects in XML. An element named after a collection property, such as Profiles, contains the items of the collection, and PostSharp adds each item to the collection in turn. PostSharp reports PS0263 on the item element when the collection refuses the item:

  • <Item> is the item, for example {LoggingProfile Name="Orders"}.
  • <Collection> is the type and the property of the collection, for example PostSharp.Patterns.Diagnostics.LoggingBuildTimeConfiguration.Profiles.
  • <Reason> is the message of the exception that the collection threw.

The collection of logging profiles is indexed by the name of the profile, ignoring case, so two LoggingProfile elements with the same Name in the same Logging element report PS0263 on the second one. PostSharp skips the item and goes on reading the file to report the other mistakes it finds.

In the following example, postsharp.config defines the Orders profile twice.

<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.postsharp.org/1.0/configuration">
  <Logging xmlns="clr-namespace:PostSharp.Patterns.Diagnostics;assembly:PostSharp.Patterns.Diagnostics">
    <Profiles>
      <LoggingProfile Name="Orders">
        <DefaultOptions>
          <LoggingOptions IncludeParameterValue="True" />
        </DefaultOptions>
      </LoggingProfile>
      <!-- A second profile with the same name: profile names must be unique, ignoring case. -->
      <LoggingProfile Name="Orders">
        <DefaultOptions>
          <LoggingOptions IncludeReturnValue="True" />
        </DefaultOptions>
      </LoggingProfile>
    </Profiles>
  </Logging>
</Project>
using System;
using PostSharp.Patterns.Diagnostics;
using PostSharp.Patterns.Diagnostics.Backends.Console;

namespace Errors.PS0263_Error;

public class OrderService
{
    // postsharp.config defines the Orders profile twice.
    [Log( "Orders" )]
    public decimal GetPrice( string product, int quantity )
    {
        return quantity * 2.5m;
    }
}

public static class Program
{
    public static void Main()
    {
        LoggingServices.DefaultBackend = new ConsoleLoggingBackend();

        Console.WriteLine( $"Price: {new OrderService().GetPrice( "Coffee", 2 )}" );
    }
}
error PS0263: postsharp.config(11,8): Cannot add {LoggingProfile Name="Orders"} to PostSharp.Patterns.Diagnostics.LoggingBuildTimeConfiguration.Profiles: An item with the same key has already been added. Key: Orders.

Resolution

Give each item a unique name. When the two elements describe the same logging profile, merge their options into one LoggingProfile element. When they describe different profiles, rename one of them, and use the new name in the LogAttribute instances that refer to it.

To change a profile that another postsharp.config file defines, for example a file of the solution, define the profile in the postsharp.config of the project instead of repeating it in the same file: PostSharp merges the profiles of different files by name.

In the following example, the Orders profile is defined once, with the options of both elements, and the log records include the parameter values and the return value.

<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.postsharp.org/1.0/configuration">
  <Logging xmlns="clr-namespace:PostSharp.Patterns.Diagnostics;assembly:PostSharp.Patterns.Diagnostics">
    <Profiles>
      <!-- One profile per name, with the options of both former elements. -->
      <LoggingProfile Name="Orders">
        <DefaultOptions>
          <LoggingOptions IncludeParameterValue="True" IncludeReturnValue="True" />
        </DefaultOptions>
      </LoggingProfile>
    </Profiles>
  </Logging>
</Project>
using System;
using PostSharp.Patterns.Diagnostics;
using PostSharp.Patterns.Diagnostics.Backends.Console;

namespace Errors.PS0263_Fixed;

public class OrderService
{
    // postsharp.config defines the Orders profile once.
    [Log( "Orders" )]
    public decimal GetPrice( string product, int quantity )
    {
        return quantity * 2.5m;
    }
}

public static class Program
{
    public static void Main()
    {
        LoggingServices.DefaultBackend = new ConsoleLoggingBackend();

        Console.WriteLine( $"Price: {new OrderService().GetPrice( "Coffee", 2 )}" );
    }
}
Debug     | Trace  | OrderService.GetPrice("Coffee", 2) | Starting.
Debug     | Trace  | OrderService.GetPrice("Coffee", 2) | Succeeded: returnValue = {5.0}.
Price: 5.0

See Also

Reference

LoggingProfile
LoggingProfileCollection

Other Resources

Configuration File Schema Reference
Configuring Projects Using postsharp.config
Formatting Log Records