castleproject / Core

Castle Core, including Castle DynamicProxy, Logging Services and DictionaryAdapter
http://www.castleproject.org/
Other
2.2k stars 467 forks source link

Nested custom attribute types do not get replicated #638

Closed stakx closed 1 year ago

stakx commented 1 year ago

637 incidentally revealed that custom attributes do not get replicated if their custom attribute type is a nested type. Given these two tests:

namespace Castle.DynamicProxy.Tests;

using System;

using NUnit.Framework;

[TestFixture]
public class Tests : BasePEVerifyTestCase
{
    [Test]
    public void Nested_non_inherited_attribute_is_replicated()
    {
        var proxy = generator.CreateInterfaceProxyWithoutTarget<IHasNestedNonInheritedAttribute>();
        var proxyType = proxy.GetType();
        var customAttributesOnProxyType = proxyType.GetCustomAttributes(typeof(NestedNonInheritedAttribute), inherit: false);
        CollectionAssert.IsNotEmpty(customAttributesOnProxyType);
    }

    [Test]
    public void Non_nested_non_inherited_attribute_is_replicated()
    {
        var proxy = generator.CreateInterfaceProxyWithoutTarget<IHasNonNestedNonInheritedAttribute>();
        var proxyType = proxy.GetType();
        var customAttributesOnProxyType = proxyType.GetCustomAttributes(typeof(NonNestedNonInheritedAttribute), inherit: false);
        CollectionAssert.IsNotEmpty(customAttributesOnProxyType);
    }

    [NestedNonInherited]
    public interface IHasNestedNonInheritedAttribute { }

    [NonNestedNonInherited]
    public interface IHasNonNestedNonInheritedAttribute { }

    [AttributeUsage(AttributeTargets.Interface, Inherited = false)]
    public sealed class NestedNonInheritedAttribute : Attribute { }
}

// NOTE: it is relevant to the above tests that the following type not be a nested type!

[AttributeUsage(AttributeTargets.Interface, Inherited = false)]
public sealed class NonNestedNonInheritedAttribute : Attribute { }

Only of of the tests fails, more specifically, Nested_non_inherited_attribute_is_replicated.

The problem is likely caused here:

https://github.com/castleproject/Core/blob/c6d7a165ac3050ebfc70debabe52ee6624a97bdf/src/Castle.Core/DynamicProxy/Internal/AttributeUtil.cs#L188

We should probably augment this test with an additional condition ... && attribute.IsNestedPublic == false.

... or was there a specific reason against replicating nested custom attribute types?