I’m creating a type with that logic:
AssemblyName encaseModularAsemblyName = new AssemblyName("ModularEncasedAssembly_" + Guid.NewGuid());
AssemblyBuilder encaseModularAssemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(encaseModularAsemblyName, AssemblyBuilderAccess.RunAndCollect);
ModuleBuilder moduleBuilder = encaseModularAssemblyBuilder.DefineDynamicModule("MainEncaseModule");
Every time a got error: ‘A non-collectible assembly may not reference a collectible assembly.’
I understand that issue comes from ‘RunAndCollect’, but i can’t set ‘Run’ in this case. I cannot just add new assemblies each time, its lifelong application
@bloodboilAaromatic
Summary
The error “A non‑collectible assembly may not reference a collectible assembly.” means that a dynamic assembly created with AssemblyBuilderAccess.RunAndCollect (collectible) is trying to reference a type that lives in a normal, non‑collectible assembly.
Why it happens
- A collectible assembly can only reference other collectible assemblies.
- If the generated type inherits from, implements, or contains members of a type defined in a regular assembly (e.g., your main project assembly or a third‑party library), the CLR blocks the creation and throws the exception.
What you can do
- Make the dynamic assembly non‑collectible
- Create the assembly with
AssemblyBuilderAccess.Run (or RunAndSave if you need to persist it). This allows it to reference any normal assembly, but the assembly will not be unloadable via the collectible mechanism.
- If you need unloadability, isolate the whole dynamic assembly in a collectible
AssemblyLoadContext (available on .NET Core/.NET 5+). Define the dynamic assembly inside that context with non‑collectible access; the context itself can be unloaded later.
- Remove the illegal reference
- Redesign the generated type so it does not directly depend on types from non‑collectible assemblies. You can define required interfaces or base classes inside the dynamic assembly and use wrappers to interact with external libraries.
- Validate the environment
- Ensure you are running on a runtime that supports collectible
AssemblyLoadContext (e.g., .NET Core 3.0+). On the full .NET Framework collectible assemblies are not supported.
Next steps
- Identify which external types the dynamic type is referencing.
- Choose either the non‑collectible approach (simpler) or the
AssemblyLoadContext approach if you must unload the generated code.
- Adjust your project’s target framework/runtime accordingly.
Note: The answer is based on general .NET behavior; specific library constraints (e.g., Aspose) were not found in the provided evidence.
I could not fully verify this explanation against the retrieved sources. Please double-check the behaviour in your environment and confirm the exact SDK/version.
@bloodboilAaromatic
There is no use of Aspose.Words API in the provided code sample. Could you please share code involving Aspose.Words and reproducing the issue? Please also share a template and data, if needed for the reproduction.
I dunno how to provide you a code, cause it’s a little bit complicated but main logic is that u creating with reflection a new type with a assemblyBuilder and setting AssemblyBuilderAccess equals to a RunAndCollect.
after that passing it to
ReportingEngine templateEngine = new ReportingEngine();
var reflexionTest = reflexTunedReportingEngineTypes.First();
templateEngine.BuildReport(documentBuilder.Document, reflexionTest, "reflexionTest");
Will cause: ‘A non-collectible assembly may not reference a collectible assembly.’
case is simple:
<<foreach [in reflexionTest]>>
Main Level:
<<[Field_9]>> - <<[Field_10]>>
<</foreach>>
Code for reflection is something like:
var typeName = $"Type_{this.Id}";
var typeBuilder = moduleBuilder.DefineType(
typeName,
TypeAttributes.Public | TypeAttributes.Class | TypeAttributes.Sealed
);
foreach(var prop in properties){
CreateProperty(...
}
var elementType = typeBuilder.CreateType();
return elementType.MakeArrayType();
private void CreateProperty(TypeBuilder typeBuilder, string propertyName, Type propertyType)
{
// Create backing field
var fieldBuilder = typeBuilder.DefineField($"_{propertyName}", propertyType, FieldAttributes.Private);
// Create property
var propertyBuilder = typeBuilder.DefineProperty(propertyName, PropertyAttributes.None, propertyType, null);
// Create getter method
var getMethod = typeBuilder.DefineMethod($"get_{propertyName}",
MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig,
propertyType, Type.EmptyTypes);
var getIl = getMethod.GetILGenerator();
getIl.Emit(OpCodes.Ldarg_0);
getIl.Emit(OpCodes.Ldfld, fieldBuilder);
getIl.Emit(OpCodes.Ret);
// Create setter method
var setMethod = typeBuilder.DefineMethod($"set_{propertyName}",
MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig,
null, new[] { propertyType });
var setIl = setMethod.GetILGenerator();
setIl.Emit(OpCodes.Ldarg_0);
setIl.Emit(OpCodes.Ldarg_1);
setIl.Emit(OpCodes.Stfld, fieldBuilder);
setIl.Emit(OpCodes.Ret);
// Assign methods to property
propertyBuilder.SetGetMethod(getMethod);
propertyBuilder.SetSetMethod(setMethod);
}
And instantiate data with code like:
Type elementType = type.GetElementType();
Array resultArray = Array.CreateInstance(elementType, encasedProcessedData.Count);
for(int i =0; i< resultArray.Count; i++){
object element = Activator.CreateInstance(elementType);
foreach(var field in elementType.GetProperties() || GetFields())
field.SetValue(element, 'yourdata')
}
resultArray.SetValue(element, i)
}
That raw code, but something… , i really cannot provide u all the code, and just ‘cut’ it from my project
@bloodboilAaromatic
Unfortunately, the details are not enough to reproduce the issue. The only thing I can suggest to try is disabling reflection optimization before building any report as follows:
ReportingEngine.UseReflectionOptimization = false;
See Optimizing Reflection Calls for more information.
1 Like
Yeah, looks like that exactly what i’m looking for, error is gone
1 Like