diff --git a/src/JasperFx/IServiceContainer.cs b/src/JasperFx/IServiceContainer.cs
index fa21cba..c554066 100644
--- a/src/JasperFx/IServiceContainer.cs
+++ b/src/JasperFx/IServiceContainer.cs
@@ -1,3 +1,4 @@
+using System.Diagnostics.CodeAnalysis;
using JasperFx.CodeGeneration.Frames;
using Microsoft.Extensions.DependencyInjection;
@@ -25,7 +26,9 @@ public interface IServiceContainer
///
///
///
- T QuickBuild();
+ [RequiresUnreferencedCode("QuickBuild reflects over T's public constructors and resolves [FromKeyedServices] parameters by closing IFinder via CloseAndBuildAs.")]
+ [RequiresDynamicCode("CloseAndBuildAs uses MakeGenericType + Activator.CreateInstance on IFinder.")]
+ T QuickBuild<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] T>();
///
/// Polyfill to make IServiceProvider work like Lamar's ability
@@ -34,8 +37,10 @@ public interface IServiceContainer
///
///
///
- object QuickBuild(Type concreteType);
-
+ [RequiresUnreferencedCode("QuickBuild reflects over concreteType's public constructors and resolves [FromKeyedServices] parameters by closing IFinder via CloseAndBuildAs.")]
+ [RequiresDynamicCode("CloseAndBuildAs uses MakeGenericType + Activator.CreateInstance on IFinder.")]
+ object QuickBuild([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type concreteType);
+
IServiceProvider Services { get; }
T GetInstance();
IReadOnlyList GetAllInstances();
diff --git a/src/JasperFx/ServiceContainer.cs b/src/JasperFx/ServiceContainer.cs
index 666f116..1c19c40 100644
--- a/src/JasperFx/ServiceContainer.cs
+++ b/src/JasperFx/ServiceContainer.cs
@@ -1,3 +1,4 @@
+using System.Diagnostics.CodeAnalysis;
using ImTools;
using JasperFx.CodeGeneration.Frames;
using JasperFx.CodeGeneration.Services;
@@ -74,6 +75,8 @@ public bool HasRegistrationFor()
return DefaultFor(typeof(T));
}
+ [UnconditionalSuppressMessage("Trimming", "IL2067:DynamicallyAccessedMembers",
+ Justification = "Builds a transient self-binding ServiceDescriptor for each MethodCall.HandlerType so Wolverine can wire constructor dependencies into generated code. Handler types are reached from Wolverine's IHandlerDiscovery surface, which is itself an annotated reflective entry point — handler types preserve their public constructors transitively, and a missing public ctor surfaces as the explicit NotSupportedException below rather than as a silent runtime failure.")]
public IEnumerable TryCreateConstructorFrames(IEnumerable calls)
{
if (calls.All(x => x.Method.IsStatic)) return new List();
@@ -206,6 +209,8 @@ public static bool IsEnumerable(Type type)
return false;
}
+ [UnconditionalSuppressMessage("Trimming", "IL2067:DynamicallyAccessedMembers",
+ Justification = "The IsPublic + IsConcrete branch below auto-registers a self-binding ServiceDescriptor for public concrete types that weren't explicitly registered. Public concrete types reached via the family lookup either come from typeof(T) (compiler-preserved) or from user-supplied registrations whose constructors the user must keep alive. A missing public ctor at activation time surfaces from ConstructorPlan.TryBuildPlan as an InvalidPlan, not a silent failure.")]
private ServiceFamily findFamily(Type serviceType)
{
if (_families.TryFind(serviceType, out var family)) return family;
@@ -287,7 +292,7 @@ public IReadOnlyList FindAll(Type serviceType, List PlanFor(descriptor, trail)).ToArray();
}
- public object BuildFromType(Type concreteType)
+ public object BuildFromType([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type concreteType)
{
var constructor = concreteType.GetConstructors().Single();
var dependencies = constructor.GetParameters().Select(x => _provider.GetService(x.ParameterType)).ToArray();
@@ -306,11 +311,13 @@ public bool HasMultiplesOf(Type variableType)
///
///
///
- public T QuickBuild()
+ [RequiresUnreferencedCode("QuickBuild reflects over T's public constructors and resolves [FromKeyedServices] parameters by closing IFinder via CloseAndBuildAs. The trimmer may remove types reached only through that closure.")]
+ [RequiresDynamicCode("CloseAndBuildAs uses MakeGenericType + Activator.CreateInstance on IFinder.")]
+ public T QuickBuild<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] T>()
{
return (T)QuickBuild(typeof(T));
}
-
+
///
/// Polyfill to make IServiceProvider work like Lamar's ability
/// to create unknown concrete types
@@ -318,7 +325,9 @@ public T QuickBuild()
///
///
///
- public object QuickBuild(Type concreteType)
+ [RequiresUnreferencedCode("QuickBuild reflects over concreteType's public constructors and resolves [FromKeyedServices] parameters by closing IFinder via CloseAndBuildAs. The trimmer may remove types reached only through that closure.")]
+ [RequiresDynamicCode("CloseAndBuildAs uses MakeGenericType + Activator.CreateInstance on IFinder.")]
+ public object QuickBuild([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type concreteType)
{
var constructor = concreteType.GetConstructors().Single();
var args = constructor
@@ -329,7 +338,7 @@ public object QuickBuild(Type concreteType)
{
return typeof(IFinder<>).CloseAndBuildAs(x.ParameterType).Find(_provider, att.Key.ToString());
}
-
+
return _provider.GetService(x.ParameterType);
})
.ToArray();