From c3a415eb932c91f9c024c51dfa9de60a3370b2d7 Mon Sep 17 00:00:00 2001 From: Simon Ferquel Date: Fri, 12 Jul 2024 18:02:01 +0200 Subject: [PATCH 1/3] When Castle.Core is loaded in a collectible Assembly Load Context, use AssemblyBuilderAccess.RunAndCollect by default --- .../AssemblyBuilderAccessDefaults.cs | 25 +++++++++++++++++++ .../DictionaryAdapterFactory.cs | 2 +- src/Castle.Core/DynamicProxy/ModuleScope.cs | 4 +-- 3 files changed, 28 insertions(+), 3 deletions(-) create mode 100644 src/Castle.Core/AssemblyBuilderAccessDefaults.cs diff --git a/src/Castle.Core/AssemblyBuilderAccessDefaults.cs b/src/Castle.Core/AssemblyBuilderAccessDefaults.cs new file mode 100644 index 0000000000..bf14afbd65 --- /dev/null +++ b/src/Castle.Core/AssemblyBuilderAccessDefaults.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection.Emit; +using System.Text; +using System.Threading.Tasks; + +namespace Castle +{ + public static class AssemblyBuilderAccessDefaults + { +#if NET + // If Castle.Core is loaded in a collectible AssemblyLoadContext, the generated assembly should be collectible as well by default. + static readonly AssemblyBuilderAccess _automatic = System.Runtime.Loader.AssemblyLoadContext.GetLoadContext(typeof(AssemblyBuilderAccessDefaults).Assembly).IsCollectible ? AssemblyBuilderAccess.RunAndCollect : AssemblyBuilderAccess.Run; +#else + static readonly AssemblyBuilderAccess _automatic = AssemblyBuilderAccess.Run; +#endif + static AssemblyBuilderAccess? _override; + public static AssemblyBuilderAccess Default + { + get => _override ?? _automatic; + set => _override = value; + } + } +} diff --git a/src/Castle.Core/Components.DictionaryAdapter/DictionaryAdapterFactory.cs b/src/Castle.Core/Components.DictionaryAdapter/DictionaryAdapterFactory.cs index a2cb08a60d..0f31510fbf 100644 --- a/src/Castle.Core/Components.DictionaryAdapter/DictionaryAdapterFactory.cs +++ b/src/Castle.Core/Components.DictionaryAdapter/DictionaryAdapterFactory.cs @@ -148,7 +148,7 @@ private object InternalGetAdapter(Type type, IDictionary dictionary, PropertyDes private static TypeBuilder CreateTypeBuilder(Type type) { var assemblyName = new AssemblyName("CastleDictionaryAdapterAssembly"); - var assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run); + var assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccessDefaults.Default); var moduleBuilder = assemblyBuilder.DefineDynamicModule("CastleDictionaryAdapterModule"); return CreateAdapterType(type, moduleBuilder); } diff --git a/src/Castle.Core/DynamicProxy/ModuleScope.cs b/src/Castle.Core/DynamicProxy/ModuleScope.cs index b70b10984e..d9f082f4df 100644 --- a/src/Castle.Core/DynamicProxy/ModuleScope.cs +++ b/src/Castle.Core/DynamicProxy/ModuleScope.cs @@ -335,9 +335,9 @@ private ModuleBuilder CreateModule(bool signStrongName) { #if FEATURE_APPDOMAIN var assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly( - assemblyName, AssemblyBuilderAccess.Run); + assemblyName, AssemblyBuilderAccessDefaults.Default); #else - var assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run); + var assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccessDefaults.Default); #endif var module = assemblyBuilder.DefineDynamicModule(moduleName); From 713d3a4696a68c852e7cc7a0dc6fe433490abf5f Mon Sep 17 00:00:00 2001 From: Simon Ferquel Date: Fri, 12 Jul 2024 18:25:05 +0200 Subject: [PATCH 2/3] Added XML Doc and update API files --- ref/Castle.Core-net462.cs | 7 +++++++ ref/Castle.Core-net6.0.cs | 7 +++++++ ref/Castle.Core-netstandard2.0.cs | 7 +++++++ ref/Castle.Core-netstandard2.1.cs | 7 +++++++ src/Castle.Core/AssemblyBuilderAccessDefaults.cs | 5 +++++ 5 files changed, 33 insertions(+) diff --git a/ref/Castle.Core-net462.cs b/ref/Castle.Core-net462.cs index e811e9fd7f..44bc69a0e5 100644 --- a/ref/Castle.Core-net462.cs +++ b/ref/Castle.Core-net462.cs @@ -3,6 +3,13 @@ [assembly: System.Runtime.CompilerServices.InternalsVisibleTo(@"Castle.Core.Tests, PublicKey=002400000480000094000000060200000024000052534131000400000100010077f5e87030dadccce6902c6adab7a987bd69cb5819991531f560785eacfc89b6fcddf6bb2a00743a7194e454c0273447fc6eec36474ba8e5a3823147d214298e4f9a631b1afee1a51ffeae4672d498f14b000e3d321453cdd8ac064de7e1cf4d222b7e81f54d4fd46725370d702a05b48738cc29d09228f1aa722ae1a9ca02fb")] [assembly: System.Runtime.InteropServices.ComVisible(false)] [assembly: System.Runtime.Versioning.TargetFramework(".NETFramework,Version=v4.6.2", FrameworkDisplayName=".NET Framework 4.6.2")] +namespace Castle +{ + public static class AssemblyBuilderAccessDefaults + { + public static System.Reflection.Emit.AssemblyBuilderAccess Default { get; set; } + } +} namespace Castle.Components.DictionaryAdapter { public abstract class AbstractDictionaryAdapter : System.Collections.ICollection, System.Collections.IDictionary, System.Collections.IEnumerable diff --git a/ref/Castle.Core-net6.0.cs b/ref/Castle.Core-net6.0.cs index 38e7bed03c..8bcfe45506 100644 --- a/ref/Castle.Core-net6.0.cs +++ b/ref/Castle.Core-net6.0.cs @@ -3,6 +3,13 @@ [assembly: System.Runtime.CompilerServices.InternalsVisibleTo(@"Castle.Core.Tests, PublicKey=002400000480000094000000060200000024000052534131000400000100010077f5e87030dadccce6902c6adab7a987bd69cb5819991531f560785eacfc89b6fcddf6bb2a00743a7194e454c0273447fc6eec36474ba8e5a3823147d214298e4f9a631b1afee1a51ffeae4672d498f14b000e3d321453cdd8ac064de7e1cf4d222b7e81f54d4fd46725370d702a05b48738cc29d09228f1aa722ae1a9ca02fb")] [assembly: System.Runtime.InteropServices.ComVisible(false)] [assembly: System.Runtime.Versioning.TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName=".NET 6.0")] +namespace Castle +{ + public static class AssemblyBuilderAccessDefaults + { + public static System.Reflection.Emit.AssemblyBuilderAccess Default { get; set; } + } +} namespace Castle.Components.DictionaryAdapter { public abstract class AbstractDictionaryAdapter : System.Collections.ICollection, System.Collections.IDictionary, System.Collections.IEnumerable diff --git a/ref/Castle.Core-netstandard2.0.cs b/ref/Castle.Core-netstandard2.0.cs index 9e8efdf470..f73af96231 100644 --- a/ref/Castle.Core-netstandard2.0.cs +++ b/ref/Castle.Core-netstandard2.0.cs @@ -3,6 +3,13 @@ [assembly: System.Runtime.CompilerServices.InternalsVisibleTo(@"Castle.Core.Tests, PublicKey=002400000480000094000000060200000024000052534131000400000100010077f5e87030dadccce6902c6adab7a987bd69cb5819991531f560785eacfc89b6fcddf6bb2a00743a7194e454c0273447fc6eec36474ba8e5a3823147d214298e4f9a631b1afee1a51ffeae4672d498f14b000e3d321453cdd8ac064de7e1cf4d222b7e81f54d4fd46725370d702a05b48738cc29d09228f1aa722ae1a9ca02fb")] [assembly: System.Runtime.InteropServices.ComVisible(false)] [assembly: System.Runtime.Versioning.TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName=".NET Standard 2.0")] +namespace Castle +{ + public static class AssemblyBuilderAccessDefaults + { + public static System.Reflection.Emit.AssemblyBuilderAccess Default { get; set; } + } +} namespace Castle.Components.DictionaryAdapter { public abstract class AbstractDictionaryAdapter : System.Collections.ICollection, System.Collections.IDictionary, System.Collections.IEnumerable diff --git a/ref/Castle.Core-netstandard2.1.cs b/ref/Castle.Core-netstandard2.1.cs index 1a81b5e911..226a276bec 100644 --- a/ref/Castle.Core-netstandard2.1.cs +++ b/ref/Castle.Core-netstandard2.1.cs @@ -3,6 +3,13 @@ [assembly: System.Runtime.CompilerServices.InternalsVisibleTo(@"Castle.Core.Tests, PublicKey=002400000480000094000000060200000024000052534131000400000100010077f5e87030dadccce6902c6adab7a987bd69cb5819991531f560785eacfc89b6fcddf6bb2a00743a7194e454c0273447fc6eec36474ba8e5a3823147d214298e4f9a631b1afee1a51ffeae4672d498f14b000e3d321453cdd8ac064de7e1cf4d222b7e81f54d4fd46725370d702a05b48738cc29d09228f1aa722ae1a9ca02fb")] [assembly: System.Runtime.InteropServices.ComVisible(false)] [assembly: System.Runtime.Versioning.TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName=".NET Standard 2.1")] +namespace Castle +{ + public static class AssemblyBuilderAccessDefaults + { + public static System.Reflection.Emit.AssemblyBuilderAccess Default { get; set; } + } +} namespace Castle.Components.DictionaryAdapter { public abstract class AbstractDictionaryAdapter : System.Collections.ICollection, System.Collections.IDictionary, System.Collections.IEnumerable diff --git a/src/Castle.Core/AssemblyBuilderAccessDefaults.cs b/src/Castle.Core/AssemblyBuilderAccessDefaults.cs index bf14afbd65..e8987581af 100644 --- a/src/Castle.Core/AssemblyBuilderAccessDefaults.cs +++ b/src/Castle.Core/AssemblyBuilderAccessDefaults.cs @@ -16,6 +16,11 @@ public static class AssemblyBuilderAccessDefaults static readonly AssemblyBuilderAccess _automatic = AssemblyBuilderAccess.Run; #endif static AssemblyBuilderAccess? _override; + + /// + /// Get or set the default to use when creating dynamic assemblies. + /// On .Net Core, the default is if Castle.Core is loaded in a collectible AssemblyLoadContext. + /// public static AssemblyBuilderAccess Default { get => _override ?? _automatic; From ff0fcde90cfd2b6dac1071c74d4109a162ed2ecb Mon Sep 17 00:00:00 2001 From: Simon Ferquel Date: Fri, 12 Jul 2024 19:02:35 +0200 Subject: [PATCH 3/3] Applying coding conventions --- ref/Castle.Core-net462.cs | 11 ++--- ref/Castle.Core-net6.0.cs | 11 ++--- ref/Castle.Core-netstandard2.0.cs | 11 ++--- ref/Castle.Core-netstandard2.1.cs | 11 ++--- .../AssemblyBuilderAccessDefaults.cs | 30 -------------- .../DictionaryAdapterFactory.cs | 1 + .../AssemblyBuilderAccessDefaults.cs | 40 +++++++++++++++++++ 7 files changed, 57 insertions(+), 58 deletions(-) delete mode 100644 src/Castle.Core/AssemblyBuilderAccessDefaults.cs create mode 100644 src/Castle.Core/DynamicProxy/AssemblyBuilderAccessDefaults.cs diff --git a/ref/Castle.Core-net462.cs b/ref/Castle.Core-net462.cs index 44bc69a0e5..bcf1d6f034 100644 --- a/ref/Castle.Core-net462.cs +++ b/ref/Castle.Core-net462.cs @@ -3,13 +3,6 @@ [assembly: System.Runtime.CompilerServices.InternalsVisibleTo(@"Castle.Core.Tests, PublicKey=002400000480000094000000060200000024000052534131000400000100010077f5e87030dadccce6902c6adab7a987bd69cb5819991531f560785eacfc89b6fcddf6bb2a00743a7194e454c0273447fc6eec36474ba8e5a3823147d214298e4f9a631b1afee1a51ffeae4672d498f14b000e3d321453cdd8ac064de7e1cf4d222b7e81f54d4fd46725370d702a05b48738cc29d09228f1aa722ae1a9ca02fb")] [assembly: System.Runtime.InteropServices.ComVisible(false)] [assembly: System.Runtime.Versioning.TargetFramework(".NETFramework,Version=v4.6.2", FrameworkDisplayName=".NET Framework 4.6.2")] -namespace Castle -{ - public static class AssemblyBuilderAccessDefaults - { - public static System.Reflection.Emit.AssemblyBuilderAccess Default { get; set; } - } -} namespace Castle.Components.DictionaryAdapter { public abstract class AbstractDictionaryAdapter : System.Collections.ICollection, System.Collections.IDictionary, System.Collections.IEnumerable @@ -2483,6 +2476,10 @@ public virtual void MethodsInspected() { } public virtual void NonProxyableMemberNotification(System.Type type, System.Reflection.MemberInfo memberInfo) { } public virtual bool ShouldInterceptMethod(System.Type type, System.Reflection.MethodInfo methodInfo) { } } + public static class AssemblyBuilderAccessDefaults + { + public static System.Reflection.Emit.AssemblyBuilderAccess Default { get; set; } + } public class CustomAttributeInfo : System.IEquatable { public CustomAttributeInfo(System.Reflection.ConstructorInfo constructor, object[] constructorArgs) { } diff --git a/ref/Castle.Core-net6.0.cs b/ref/Castle.Core-net6.0.cs index 8bcfe45506..d6295af16f 100644 --- a/ref/Castle.Core-net6.0.cs +++ b/ref/Castle.Core-net6.0.cs @@ -3,13 +3,6 @@ [assembly: System.Runtime.CompilerServices.InternalsVisibleTo(@"Castle.Core.Tests, PublicKey=002400000480000094000000060200000024000052534131000400000100010077f5e87030dadccce6902c6adab7a987bd69cb5819991531f560785eacfc89b6fcddf6bb2a00743a7194e454c0273447fc6eec36474ba8e5a3823147d214298e4f9a631b1afee1a51ffeae4672d498f14b000e3d321453cdd8ac064de7e1cf4d222b7e81f54d4fd46725370d702a05b48738cc29d09228f1aa722ae1a9ca02fb")] [assembly: System.Runtime.InteropServices.ComVisible(false)] [assembly: System.Runtime.Versioning.TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName=".NET 6.0")] -namespace Castle -{ - public static class AssemblyBuilderAccessDefaults - { - public static System.Reflection.Emit.AssemblyBuilderAccess Default { get; set; } - } -} namespace Castle.Components.DictionaryAdapter { public abstract class AbstractDictionaryAdapter : System.Collections.ICollection, System.Collections.IDictionary, System.Collections.IEnumerable @@ -2451,6 +2444,10 @@ public virtual void MethodsInspected() { } public virtual void NonProxyableMemberNotification(System.Type type, System.Reflection.MemberInfo memberInfo) { } public virtual bool ShouldInterceptMethod(System.Type type, System.Reflection.MethodInfo methodInfo) { } } + public static class AssemblyBuilderAccessDefaults + { + public static System.Reflection.Emit.AssemblyBuilderAccess Default { get; set; } + } public class CustomAttributeInfo : System.IEquatable { public CustomAttributeInfo(System.Reflection.ConstructorInfo constructor, object[] constructorArgs) { } diff --git a/ref/Castle.Core-netstandard2.0.cs b/ref/Castle.Core-netstandard2.0.cs index f73af96231..81a453c224 100644 --- a/ref/Castle.Core-netstandard2.0.cs +++ b/ref/Castle.Core-netstandard2.0.cs @@ -3,13 +3,6 @@ [assembly: System.Runtime.CompilerServices.InternalsVisibleTo(@"Castle.Core.Tests, PublicKey=002400000480000094000000060200000024000052534131000400000100010077f5e87030dadccce6902c6adab7a987bd69cb5819991531f560785eacfc89b6fcddf6bb2a00743a7194e454c0273447fc6eec36474ba8e5a3823147d214298e4f9a631b1afee1a51ffeae4672d498f14b000e3d321453cdd8ac064de7e1cf4d222b7e81f54d4fd46725370d702a05b48738cc29d09228f1aa722ae1a9ca02fb")] [assembly: System.Runtime.InteropServices.ComVisible(false)] [assembly: System.Runtime.Versioning.TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName=".NET Standard 2.0")] -namespace Castle -{ - public static class AssemblyBuilderAccessDefaults - { - public static System.Reflection.Emit.AssemblyBuilderAccess Default { get; set; } - } -} namespace Castle.Components.DictionaryAdapter { public abstract class AbstractDictionaryAdapter : System.Collections.ICollection, System.Collections.IDictionary, System.Collections.IEnumerable @@ -2449,6 +2442,10 @@ public virtual void MethodsInspected() { } public virtual void NonProxyableMemberNotification(System.Type type, System.Reflection.MemberInfo memberInfo) { } public virtual bool ShouldInterceptMethod(System.Type type, System.Reflection.MethodInfo methodInfo) { } } + public static class AssemblyBuilderAccessDefaults + { + public static System.Reflection.Emit.AssemblyBuilderAccess Default { get; set; } + } public class CustomAttributeInfo : System.IEquatable { public CustomAttributeInfo(System.Reflection.ConstructorInfo constructor, object[] constructorArgs) { } diff --git a/ref/Castle.Core-netstandard2.1.cs b/ref/Castle.Core-netstandard2.1.cs index 226a276bec..1bd78e01e0 100644 --- a/ref/Castle.Core-netstandard2.1.cs +++ b/ref/Castle.Core-netstandard2.1.cs @@ -3,13 +3,6 @@ [assembly: System.Runtime.CompilerServices.InternalsVisibleTo(@"Castle.Core.Tests, PublicKey=002400000480000094000000060200000024000052534131000400000100010077f5e87030dadccce6902c6adab7a987bd69cb5819991531f560785eacfc89b6fcddf6bb2a00743a7194e454c0273447fc6eec36474ba8e5a3823147d214298e4f9a631b1afee1a51ffeae4672d498f14b000e3d321453cdd8ac064de7e1cf4d222b7e81f54d4fd46725370d702a05b48738cc29d09228f1aa722ae1a9ca02fb")] [assembly: System.Runtime.InteropServices.ComVisible(false)] [assembly: System.Runtime.Versioning.TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName=".NET Standard 2.1")] -namespace Castle -{ - public static class AssemblyBuilderAccessDefaults - { - public static System.Reflection.Emit.AssemblyBuilderAccess Default { get; set; } - } -} namespace Castle.Components.DictionaryAdapter { public abstract class AbstractDictionaryAdapter : System.Collections.ICollection, System.Collections.IDictionary, System.Collections.IEnumerable @@ -2449,6 +2442,10 @@ public virtual void MethodsInspected() { } public virtual void NonProxyableMemberNotification(System.Type type, System.Reflection.MemberInfo memberInfo) { } public virtual bool ShouldInterceptMethod(System.Type type, System.Reflection.MethodInfo methodInfo) { } } + public static class AssemblyBuilderAccessDefaults + { + public static System.Reflection.Emit.AssemblyBuilderAccess Default { get; set; } + } public class CustomAttributeInfo : System.IEquatable { public CustomAttributeInfo(System.Reflection.ConstructorInfo constructor, object[] constructorArgs) { } diff --git a/src/Castle.Core/AssemblyBuilderAccessDefaults.cs b/src/Castle.Core/AssemblyBuilderAccessDefaults.cs deleted file mode 100644 index e8987581af..0000000000 --- a/src/Castle.Core/AssemblyBuilderAccessDefaults.cs +++ /dev/null @@ -1,30 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Reflection.Emit; -using System.Text; -using System.Threading.Tasks; - -namespace Castle -{ - public static class AssemblyBuilderAccessDefaults - { -#if NET - // If Castle.Core is loaded in a collectible AssemblyLoadContext, the generated assembly should be collectible as well by default. - static readonly AssemblyBuilderAccess _automatic = System.Runtime.Loader.AssemblyLoadContext.GetLoadContext(typeof(AssemblyBuilderAccessDefaults).Assembly).IsCollectible ? AssemblyBuilderAccess.RunAndCollect : AssemblyBuilderAccess.Run; -#else - static readonly AssemblyBuilderAccess _automatic = AssemblyBuilderAccess.Run; -#endif - static AssemblyBuilderAccess? _override; - - /// - /// Get or set the default to use when creating dynamic assemblies. - /// On .Net Core, the default is if Castle.Core is loaded in a collectible AssemblyLoadContext. - /// - public static AssemblyBuilderAccess Default - { - get => _override ?? _automatic; - set => _override = value; - } - } -} diff --git a/src/Castle.Core/Components.DictionaryAdapter/DictionaryAdapterFactory.cs b/src/Castle.Core/Components.DictionaryAdapter/DictionaryAdapterFactory.cs index 0f31510fbf..366e2a4c45 100644 --- a/src/Castle.Core/Components.DictionaryAdapter/DictionaryAdapterFactory.cs +++ b/src/Castle.Core/Components.DictionaryAdapter/DictionaryAdapterFactory.cs @@ -27,6 +27,7 @@ namespace Castle.Components.DictionaryAdapter using Castle.Components.DictionaryAdapter.Xml; using Castle.Core.Internal; + using Castle.DynamicProxy; /// /// Uses Reflection.Emit to expose the properties of a dictionary diff --git a/src/Castle.Core/DynamicProxy/AssemblyBuilderAccessDefaults.cs b/src/Castle.Core/DynamicProxy/AssemblyBuilderAccessDefaults.cs new file mode 100644 index 0000000000..43fe377af8 --- /dev/null +++ b/src/Castle.Core/DynamicProxy/AssemblyBuilderAccessDefaults.cs @@ -0,0 +1,40 @@ +// Copyright 2004-2021 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + + +namespace Castle.DynamicProxy +{ + using System.Reflection.Emit; + + public static class AssemblyBuilderAccessDefaults + { +#if NET + // If Castle.Core is loaded in a collectible AssemblyLoadContext, the generated assembly should be collectible as well by default. + static readonly AssemblyBuilderAccess automatic = System.Runtime.Loader.AssemblyLoadContext.GetLoadContext(typeof(AssemblyBuilderAccessDefaults).Assembly).IsCollectible ? AssemblyBuilderAccess.RunAndCollect : AssemblyBuilderAccess.Run; +#else + static readonly AssemblyBuilderAccess automatic = AssemblyBuilderAccess.Run; +#endif + static AssemblyBuilderAccess? userSpecified; + + /// + /// Get or set the default to use when creating dynamic assemblies. + /// On .Net Core, the default is if Castle.Core is loaded in a collectible AssemblyLoadContext. + /// + public static AssemblyBuilderAccess Default + { + get => userSpecified ?? automatic; + set => userSpecified = value; + } + } +}