diff --git a/src/Castle.Core/DynamicProxy/CollectibleProxyBuilder.cs b/src/Castle.Core/DynamicProxy/CollectibleProxyBuilder.cs new file mode 100644 index 000000000..ba273d380 --- /dev/null +++ b/src/Castle.Core/DynamicProxy/CollectibleProxyBuilder.cs @@ -0,0 +1,33 @@ +// Copyright 2004-2024 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. + +#nullable enable + +namespace Castle.DynamicProxy +{ + using System.Reflection.Emit; + + /// + /// Proxy builder that causes generated assemblies to be collectible. + /// + public class CollectibleProxyBuilder : DefaultProxyBuilder + { + /// + /// Initializes a new instance of the class. + /// + public CollectibleProxyBuilder() : base(new ModuleScope(AssemblyBuilderAccess.RunAndCollect)) + { + } + } +} diff --git a/src/Castle.Core/DynamicProxy/ModuleScope.cs b/src/Castle.Core/DynamicProxy/ModuleScope.cs index af17ae2eb..1b8bb6d2d 100644 --- a/src/Castle.Core/DynamicProxy/ModuleScope.cs +++ b/src/Castle.Core/DynamicProxy/ModuleScope.cs @@ -60,7 +60,7 @@ public class ModuleScope private readonly object moduleLocker = new object(); // Specified whether the generated assemblies are intended to be saved - private readonly bool savePhysicalAssembly; + private readonly AssemblyBuilderAccess assemblyBuilderAccess; private readonly bool disableSignedModule; private readonly INamingScope namingScope; @@ -81,6 +81,16 @@ public ModuleScope(bool savePhysicalAssembly) { } + /// + /// Initializes a new instance of the class, + /// using the specified for generated assemblies. + /// + /// The desired to be used for generated assemblies. + internal ModuleScope(AssemblyBuilderAccess assemblyBuilderAccess) + : this(assemblyBuilderAccess, disableSignedModule: false, new NamingScope(), DEFAULT_ASSEMBLY_NAME, DEFAULT_FILE_NAME, DEFAULT_ASSEMBLY_NAME, DEFAULT_FILE_NAME) + { + } + /// /// Initializes a new instance of the class, allowing to specify whether the assemblies generated by this instance /// should be saved. @@ -133,8 +143,21 @@ public ModuleScope(bool savePhysicalAssembly, bool disableSignedModule, string s internal ModuleScope(bool savePhysicalAssembly, bool disableSignedModule, INamingScope namingScope, string strongAssemblyName, string strongModulePath, string weakAssemblyName, string weakModulePath) + : this( +#if FEATURE_ASSEMBLYBUILDER_SAVE + assemblyBuilderAccess: savePhysicalAssembly ? AssemblyBuilderAccess.RunAndSave : AssemblyBuilderAccess.Run, +#else + assemblyBuilderAccess: AssemblyBuilderAccess.Run, +#endif + disableSignedModule, namingScope, strongAssemblyName, strongModulePath, weakAssemblyName, weakModulePath) + { + } + + internal ModuleScope(AssemblyBuilderAccess assemblyBuilderAccess, bool disableSignedModule, INamingScope namingScope, + string strongAssemblyName, string strongModulePath, + string weakAssemblyName, string weakModulePath) { - this.savePhysicalAssembly = savePhysicalAssembly; + this.assemblyBuilderAccess = assemblyBuilderAccess; this.disableSignedModule = disableSignedModule; this.namingScope = namingScope; this.strongAssemblyName = strongAssemblyName; @@ -309,14 +332,14 @@ private ModuleBuilder CreateModule(bool signStrongName) { var assemblyName = GetAssemblyName(signStrongName); var moduleName = signStrongName ? StrongNamedModuleName : WeakNamedModuleName; -#if FEATURE_APPDOMAIN - if (savePhysicalAssembly) +#if FEATURE_APPDOMAIN && FEATURE_ASSEMBLYBUILDER_SAVE + if ((assemblyBuilderAccess & AssemblyBuilderAccess.Save) != 0) { AssemblyBuilder assemblyBuilder; try { assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly( - assemblyName, AssemblyBuilderAccess.RunAndSave, signStrongName ? StrongNamedModuleDirectory : WeakNamedModuleDirectory); + assemblyName, assemblyBuilderAccess, signStrongName ? StrongNamedModuleDirectory : WeakNamedModuleDirectory); } catch (ArgumentException e) { @@ -339,10 +362,9 @@ private ModuleBuilder CreateModule(bool signStrongName) #endif { #if FEATURE_APPDOMAIN - var assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly( - assemblyName, AssemblyBuilderAccess.Run); + var assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, assemblyBuilderAccess); #else - var assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run); + var assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(assemblyName, assemblyBuilderAccess); #endif var module = assemblyBuilder.DefineDynamicModule(moduleName); @@ -387,7 +409,7 @@ private AssemblyName GetAssemblyName(bool signStrongName) /// The path of the generated assembly file, or null if no file has been generated. public string? SaveAssembly() { - if (!savePhysicalAssembly) + if ((assemblyBuilderAccess & AssemblyBuilderAccess.Save) == 0) { return null; } @@ -433,7 +455,7 @@ private AssemblyName GetAssemblyName(bool signStrongName) /// The path of the generated assembly file, or null if no file has been generated. public string? SaveAssembly(bool strongNamed) { - if (!savePhysicalAssembly) + if ((assemblyBuilderAccess & AssemblyBuilderAccess.Save) == 0) { return null; }