Skip to content

Commit 323c03f

Browse files
authored
Merge pull request #639 from stakx/bug/nested-custom-attribute-types
Enable replication of nested custom attribute types
2 parents 9029d9f + a2e6bbe commit 323c03f

File tree

5 files changed

+127
-1
lines changed

5 files changed

+127
-1
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
# Castle Core Changelog
22

3+
## Unreleased
4+
5+
Bugfixes:
6+
- Nested custom attribute types do not get replicated (@stakx, #638)
7+
38
## 5.1.0 (2022-08-02)
49

510
Enhancements:

src/Castle.Core.Tests/DynamicProxy.Tests/ClassWithAttributesTestCase.cs

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,53 @@ public void EnsureProxyHasAttributesOnGenericArgument()
112112
Assert.IsTrue(nameProperty.IsDefined(typeof(NonInheritableAttribute), false));
113113
}
114114

115+
[Test]
116+
public void EnsureProxyHasNestedAttributesOnClassAndMethods()
117+
{
118+
var instance = (HasNestedNonInheritableAttribute)generator.CreateClassProxy(typeof(HasNestedNonInheritableAttribute), new StandardInterceptor());
119+
120+
object[] attributes = instance.GetType().GetCustomAttributes(typeof(Nested.NonInheritableAttribute), false).ToArray();
121+
Assert.AreEqual(1, attributes.Length);
122+
Assert.IsInstanceOf(typeof(Nested.NonInheritableAttribute), attributes[0]);
123+
124+
attributes = instance.GetType().GetMethod("OnMethod").GetCustomAttributes(typeof(Nested.NonInheritableAttribute), false).ToArray();
125+
Assert.AreEqual(1, attributes.Length);
126+
Assert.IsInstanceOf(typeof(Nested.NonInheritableAttribute), attributes[0]);
127+
}
128+
129+
[Test]
130+
public void EnsureProxyHasNestedAttributesOnProperties()
131+
{
132+
var proxy = generator.CreateClassProxy<HasNestedNonInheritableAttribute>();
133+
var nameProperty = proxy.GetType().GetProperty("OnProperty");
134+
Assert.IsTrue(nameProperty.IsDefined(typeof(Nested.NonInheritableAttribute), false));
135+
}
136+
137+
[Test, Ignore("Not supported. Is it possible? There seems to be no API to allow that.")]
138+
public void EnsureProxyHasNestedAttributesOnOnReturn()
139+
{
140+
var proxy = generator.CreateClassProxy<HasNestedNonInheritableAttribute>();
141+
var nameProperty = proxy.GetType().GetMethod("OnReturn").ReturnParameter;
142+
Assert.IsTrue(nameProperty.IsDefined(typeof(Nested.NonInheritableAttribute), false));
143+
}
144+
145+
[Test]
146+
public void EnsureProxyHasNestedAttributesOnParameter()
147+
{
148+
var proxy = generator.CreateClassProxy<HasNestedNonInheritableAttribute>();
149+
ParameterInfo nameProperty = proxy.GetType().GetMethod("OnParameter").GetParameters().Single();
150+
Assert.IsTrue(nameProperty.IsDefined(typeof(Nested.NonInheritableAttribute), false));
151+
}
152+
153+
[Test]
154+
[Platform(Exclude = "Mono", Reason = "Mono does not currently emit custom attributes on generic type parameters of methods. See https://github.com/mono/mono/issues/8512.")]
155+
public void EnsureProxyHasNestedAttributesOnGenericArgument()
156+
{
157+
var proxy = generator.CreateClassProxy<HasNestedNonInheritableAttribute>();
158+
var nameProperty = proxy.GetType().GetMethod("OnGenericArgument").GetGenericArguments().Single();
159+
Assert.IsTrue(nameProperty.IsDefined(typeof(Nested.NonInheritableAttribute), false));
160+
}
161+
115162
[Test]
116163
public void Can_proxy_type_with_non_inheritable_attribute_depending_on_array_of_something_via_property()
117164
{
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
// Copyright 2004-2022 Castle Project - http://www.castleproject.org/
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
namespace Castle.DynamicProxy.Tests.Classes
16+
{
17+
[Nested.NonInheritable]
18+
public class HasNestedNonInheritableAttribute
19+
{
20+
[Nested.NonInheritable]
21+
public virtual void OnMethod()
22+
{
23+
}
24+
25+
[Nested.NonInheritable]
26+
public virtual string OnProperty
27+
{
28+
get; set;
29+
}
30+
31+
[return: Nested.NonInheritable]
32+
public virtual int OnReturn()
33+
{
34+
return 1;
35+
}
36+
37+
public virtual void OnParameter([Nested.NonInheritable] int arg)
38+
{
39+
}
40+
41+
public virtual void OnGenericArgument<[Nested.NonInheritable] T>()
42+
{
43+
}
44+
}
45+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// Copyright 2004-2022 Castle Project - http://www.castleproject.org/
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
namespace Castle.DynamicProxy.Tests.Classes
16+
{
17+
using System;
18+
19+
public partial class Nested
20+
{
21+
#if FEATURE_SERIALIZATION
22+
[Serializable]
23+
#endif
24+
[AttributeUsage(AttributeTargets.All, Inherited = false)]
25+
public class NonInheritableAttribute : Attribute
26+
{
27+
}
28+
}
29+
}

src/Castle.Core/DynamicProxy/Internal/AttributeUtil.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ public static IEnumerable<CustomAttributeInfo> GetNonInheritableAttributes(this
185185
/// </summary>
186186
private static bool ShouldSkipAttributeReplication(Type attribute, bool ignoreInheritance)
187187
{
188-
if (attribute.IsPublic == false)
188+
if (attribute.IsPublic == false && attribute.IsNestedPublic == false)
189189
{
190190
return true;
191191
}

0 commit comments

Comments
 (0)