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;
}