Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 8 additions & 3 deletions src/JasperFx/IServiceContainer.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System.Diagnostics.CodeAnalysis;
using JasperFx.CodeGeneration.Frames;
using Microsoft.Extensions.DependencyInjection;

Expand Down Expand Up @@ -25,7 +26,9 @@ public interface IServiceContainer
/// <param name="provider"></param>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
T QuickBuild<T>();
[RequiresUnreferencedCode("QuickBuild reflects over T's public constructors and resolves [FromKeyedServices] parameters by closing IFinder<TParameter> via CloseAndBuildAs.")]
[RequiresDynamicCode("CloseAndBuildAs uses MakeGenericType + Activator.CreateInstance on IFinder<TParameter>.")]
T QuickBuild<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] T>();

/// <summary>
/// Polyfill to make IServiceProvider work like Lamar's ability
Expand All @@ -34,8 +37,10 @@ public interface IServiceContainer
/// <param name="provider"></param>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
object QuickBuild(Type concreteType);

[RequiresUnreferencedCode("QuickBuild reflects over concreteType's public constructors and resolves [FromKeyedServices] parameters by closing IFinder<TParameter> via CloseAndBuildAs.")]
[RequiresDynamicCode("CloseAndBuildAs uses MakeGenericType + Activator.CreateInstance on IFinder<TParameter>.")]
object QuickBuild([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type concreteType);

IServiceProvider Services { get; }
T GetInstance<T>();
IReadOnlyList<T> GetAllInstances<T>();
Expand Down
19 changes: 14 additions & 5 deletions src/JasperFx/ServiceContainer.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System.Diagnostics.CodeAnalysis;
using ImTools;
using JasperFx.CodeGeneration.Frames;
using JasperFx.CodeGeneration.Services;
Expand Down Expand Up @@ -74,6 +75,8 @@ public bool HasRegistrationFor<T>()
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<Frame> TryCreateConstructorFrames(IEnumerable<MethodCall> calls)
{
if (calls.All(x => x.Method.IsStatic)) return new List<Frame>();
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -287,7 +292,7 @@ public IReadOnlyList<ServicePlan> FindAll(Type serviceType, List<ServiceDescript
return findFamily(serviceType).Services.Select(descriptor => 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();
Expand All @@ -306,19 +311,23 @@ public bool HasMultiplesOf(Type variableType)
/// <param name="provider"></param>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public T QuickBuild<T>()
[RequiresUnreferencedCode("QuickBuild reflects over T's public constructors and resolves [FromKeyedServices] parameters by closing IFinder<TParameter> via CloseAndBuildAs. The trimmer may remove types reached only through that closure.")]
[RequiresDynamicCode("CloseAndBuildAs uses MakeGenericType + Activator.CreateInstance on IFinder<TParameter>.")]
public T QuickBuild<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] T>()
{
return (T)QuickBuild(typeof(T));
}

/// <summary>
/// Polyfill to make IServiceProvider work like Lamar's ability
/// to create unknown concrete types
/// </summary>
/// <param name="provider"></param>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public object QuickBuild(Type concreteType)
[RequiresUnreferencedCode("QuickBuild reflects over concreteType's public constructors and resolves [FromKeyedServices] parameters by closing IFinder<TParameter> via CloseAndBuildAs. The trimmer may remove types reached only through that closure.")]
[RequiresDynamicCode("CloseAndBuildAs uses MakeGenericType + Activator.CreateInstance on IFinder<TParameter>.")]
public object QuickBuild([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type concreteType)
{
var constructor = concreteType.GetConstructors().Single();
var args = constructor
Expand All @@ -329,7 +338,7 @@ public object QuickBuild(Type concreteType)
{
return typeof(IFinder<>).CloseAndBuildAs<IFinder>(x.ParameterType).Find(_provider, att.Key.ToString());
}

return _provider.GetService(x.ParameterType);
})
.ToArray();
Expand Down
Loading