Skip to content

Commit 4c5bc7a

Browse files
committed
Added AOT compatibility to facilities.
1 parent 801cede commit 4c5bc7a

File tree

10 files changed

+77
-74
lines changed

10 files changed

+77
-74
lines changed

DependencyInjection/src/AppCoreNet.Extensions.DependencyInjection.Abstractions/Facilities/FacilityBuilder.cs

Lines changed: 9 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// Copyright (c) The AppCore .NET project.
33

44
using System;
5-
using System.Linq;
5+
using System.Diagnostics.CodeAnalysis;
66
using AppCoreNet.Diagnostics;
77
using AppCoreNet.Extensions.DependencyInjection.Activator;
88
using Microsoft.Extensions.DependencyInjection;
@@ -12,7 +12,7 @@ namespace AppCoreNet.Extensions.DependencyInjection.Facilities;
1212
/// <summary>
1313
/// Provides a builder for facilities.
1414
/// </summary>
15-
public class FacilityBuilder
15+
public sealed class FacilityBuilder
1616
{
1717
/// <summary>
1818
/// Gets the <see cref="IServiceCollection"/>.
@@ -36,35 +36,23 @@ internal FacilityBuilder(IServiceCollection services, IActivator activator, Type
3636
FacilityType = facilityType;
3737
}
3838

39-
private IFacilityExtension<IFacility> CreateExtension(Type extensionType)
40-
{
41-
Type contractType = extensionType.GetInterfaces()
42-
.First(i => i.GetGenericTypeDefinition() == typeof(IFacilityExtension<>))
43-
.GenericTypeArguments[0];
44-
45-
Type extensionWrapperType = typeof(FacilityExtensionWrapper<>).MakeGenericType(contractType);
46-
object extension = Activator.CreateInstance(extensionType)!;
47-
48-
return (IFacilityExtension<IFacility>)System.Activator.CreateInstance(extensionWrapperType, extension)!;
49-
}
50-
5139
/// <summary>
5240
/// Adds an extension to the facility.
5341
/// </summary>
5442
/// <remarks>
55-
/// The type <paramref name="extensionType"/> must implement <see cref="IFacilityExtension{T}"/> with the
56-
/// type of the facility.
43+
/// The type <paramref name="extensionType"/> must implement <see cref="IFacilityExtension"/>.
5744
/// </remarks>
5845
/// <param name="extensionType">The type of the extension.</param>
5946
/// <returns>The <see cref="FacilityBuilder"/> to allow chaining.</returns>
6047
/// <exception cref="ArgumentNullException">Argument <paramref name="extensionType"/> is null.</exception>
61-
/// <exception cref="ArgumentException">Argument <paramref name="extensionType"/> does not implement <see cref="IFacilityExtension{T}"/> with the type of the facility.</exception>
62-
public FacilityBuilder AddExtension(Type extensionType)
48+
/// <exception cref="ArgumentException">Argument <paramref name="extensionType"/> does not implement <see cref="IFacilityExtension"/> with the type of the facility.</exception>
49+
public FacilityBuilder AddExtension(
50+
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type extensionType)
6351
{
6452
Ensure.Arg.NotNull(extensionType);
65-
Ensure.Arg.OfType(extensionType, typeof(IFacilityExtension<>).MakeGenericType(FacilityType));
53+
Ensure.Arg.OfType<IFacilityExtension>(extensionType);
6654

67-
IFacilityExtension<IFacility> extension = CreateExtension(extensionType);
55+
var extension = (IFacilityExtension)Activator.CreateInstance(extensionType)!;
6856
extension.ConfigureServices(Services);
6957
return this;
7058
}
@@ -82,7 +70,7 @@ public FacilityBuilder AddExtensionsFrom(Action<IFacilityExtensionReflectionBuil
8270
var reflectionBuilder = new FacilityExtensionReflectionBuilder(Activator);
8371
configure(reflectionBuilder);
8472

85-
foreach (IFacilityExtension<IFacility> extension in reflectionBuilder.Resolve(FacilityType))
73+
foreach (IFacilityExtension extension in reflectionBuilder.Resolve(FacilityType))
8674
{
8775
extension.ConfigureServices(Services);
8876
}

DependencyInjection/src/AppCoreNet.Extensions.DependencyInjection.Abstractions/Facilities/FacilityBuilder{T}.cs

Lines changed: 35 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// Copyright (c) The AppCore .NET project.
33

44
using System;
5-
using System.Linq;
5+
using System.Diagnostics.CodeAnalysis;
66
using AppCoreNet.Diagnostics;
77
using AppCoreNet.Extensions.DependencyInjection.Activator;
88
using Microsoft.Extensions.DependencyInjection;
@@ -13,12 +13,23 @@ namespace AppCoreNet.Extensions.DependencyInjection.Facilities;
1313
/// Provides a builder for facilities.
1414
/// </summary>
1515
/// <typeparam name="T">The type of the facility.</typeparam>
16-
public sealed class FacilityBuilder<T> : FacilityBuilder
16+
public sealed class FacilityBuilder<T>
1717
where T : IFacility
1818
{
19+
/// <summary>
20+
/// Gets the <see cref="IServiceCollection"/>.
21+
/// </summary>
22+
public IServiceCollection Services { get; }
23+
24+
/// <summary>
25+
/// Gets the <see cref="IActivator"/>.
26+
/// </summary>
27+
public IActivator Activator { get; }
28+
1929
internal FacilityBuilder(IServiceCollection services, IActivator activator)
20-
: base(services, activator, typeof(T))
2130
{
31+
Services = services;
32+
Activator = activator;
2233
}
2334

2435
/// <summary>
@@ -32,9 +43,13 @@ internal FacilityBuilder(IServiceCollection services, IActivator activator)
3243
/// <returns>The <see cref="FacilityBuilder{T}"/> to allow chaining.</returns>
3344
/// <exception cref="ArgumentNullException">Argument <paramref name="extensionType"/> is null.</exception>
3445
/// <exception cref="ArgumentException">Argument <paramref name="extensionType"/> does not implement <see cref="IFacilityExtension{T}"/> with the type of the facility.</exception>
35-
public new FacilityBuilder<T> AddExtension(Type extensionType)
46+
public FacilityBuilder<T> AddExtension(
47+
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type extensionType)
3648
{
37-
base.AddExtension(extensionType);
49+
Ensure.Arg.OfType<IFacilityExtension<T>>(extensionType);
50+
51+
var extension = (IFacilityExtension<T>)Activator.CreateInstance(extensionType)!;
52+
extension.ConfigureServices(Services);
3853
return this;
3954
}
4055

@@ -43,7 +58,8 @@ internal FacilityBuilder(IServiceCollection services, IActivator activator)
4358
/// </summary>
4459
/// <typeparam name="TExtension">The type of the extension.</typeparam>
4560
/// <returns>The <see cref="FacilityBuilder{T}"/> to allow chaining.</returns>
46-
public FacilityBuilder<T> AddExtension<TExtension>()
61+
public FacilityBuilder<T> AddExtension<
62+
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TExtension>()
4763
where TExtension : class, IFacilityExtension<T>
4864
{
4965
IFacilityExtension<T> extension = Activator.CreateInstance<TExtension>()!;
@@ -65,14 +81,24 @@ public FacilityBuilder<T> AddExtension(IFacilityExtension<T> extension)
6581
}
6682

6783
/// <summary>
68-
/// Adds facility extensions using a <see cref="IFacilityExtensionReflectionBuilder"/> to the <see cref="IServiceCollection"/>.
84+
/// Adds facility extensions using a <see cref="IFacilityExtensionReflectionBuilder"/> to the
85+
/// <see cref="IServiceCollection"/>.
6986
/// </summary>
7087
/// <param name="configure">The delegate used to configure the facility extension resolvers.</param>
7188
/// <returns>The <see cref="FacilityBuilder{T}"/>.</returns>
7289
/// <exception cref="ArgumentNullException">Argument <paramref name="configure"/> is null.</exception>
73-
public new FacilityBuilder<T> AddExtensionsFrom(Action<IFacilityExtensionReflectionBuilder> configure)
90+
public FacilityBuilder<T> AddExtensionsFrom(Action<IFacilityExtensionReflectionBuilder> configure)
7491
{
75-
base.AddExtensionsFrom(configure);
92+
Ensure.Arg.NotNull(configure);
93+
94+
var reflectionBuilder = new FacilityExtensionReflectionBuilder(Activator);
95+
configure(reflectionBuilder);
96+
97+
foreach (IFacilityExtension extension in reflectionBuilder.Resolve(typeof(T)))
98+
{
99+
extension.ConfigureServices(Services);
100+
}
101+
76102
return this;
77103
}
78104
}

DependencyInjection/src/AppCoreNet.Extensions.DependencyInjection.Abstractions/Facilities/FacilityExtensionReflectionBuilder.cs

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
using System;
55
using System.Collections.Generic;
6+
using System.Diagnostics.CodeAnalysis;
67
using System.Linq;
78
using AppCoreNet.Diagnostics;
89
using AppCoreNet.Extensions.DependencyInjection.Activator;
@@ -26,21 +27,18 @@ public IFacilityExtensionReflectionBuilder AddResolver(IFacilityExtensionResolve
2627
return this;
2728
}
2829

29-
public IFacilityExtensionReflectionBuilder AddResolver<T>(Action<T>? configure = null)
30+
public IFacilityExtensionReflectionBuilder AddResolver<
31+
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] T>(Action<T>? configure = null)
3032
where T : IFacilityExtensionResolver
3133
{
3234
var resolver = _activator.CreateInstance<T>()!;
3335
configure?.Invoke(resolver);
3436
return AddResolver(resolver);
3537
}
3638

37-
public IReadOnlyCollection<IFacilityExtension<IFacility>> Resolve(Type facilityType)
39+
public IReadOnlyCollection<IFacilityExtension> Resolve(Type facilityType)
3840
{
39-
Type[] facilityTypes = facilityType.GetTypesAssignableFrom()
40-
.Where(t => t.GetInterfaces().Contains(typeof(IFacility)))
41-
.ToArray();
42-
43-
return _resolvers.SelectMany(s => facilityTypes.SelectMany(s.Resolve))
41+
return _resolvers.SelectMany(s => s.Resolve(facilityType))
4442
.ToList()
4543
.AsReadOnly();
4644
}

DependencyInjection/src/AppCoreNet.Extensions.DependencyInjection.Abstractions/Facilities/FacilityExtensionWrapper.cs

Lines changed: 0 additions & 22 deletions
This file was deleted.

DependencyInjection/src/AppCoreNet.Extensions.DependencyInjection.Abstractions/Facilities/FacilityReflectionBuilder.cs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using System;
55
using System.Collections.Generic;
66
using System.Collections.ObjectModel;
7+
using System.Diagnostics.CodeAnalysis;
78
using System.Linq;
89
using AppCoreNet.Diagnostics;
910
using AppCoreNet.Extensions.DependencyInjection.Activator;
@@ -28,7 +29,8 @@ public IFacilityReflectionBuilder AddResolver(IFacilityResolver resolver)
2829
return this;
2930
}
3031

31-
public IFacilityReflectionBuilder AddResolver<T>(Action<T>? configure = null)
32+
public IFacilityReflectionBuilder AddResolver<
33+
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] T>(Action<T>? configure = null)
3234
where T : IFacilityResolver
3335
{
3436
var resolver = _activator.CreateInstance<T>()!;
@@ -43,7 +45,7 @@ public IFacilityReflectionBuilder AddExtensionsFrom(Action<IFacilityExtensionRef
4345
return this;
4446
}
4547

46-
public IReadOnlyCollection<(IFacility Facility, IReadOnlyCollection<IFacilityExtension<IFacility>>
48+
public IReadOnlyCollection<(IFacility Facility, IReadOnlyCollection<IFacilityExtension>
4749
FacilityExtensions)> Resolve()
4850
{
4951
List<IFacility> facilities =
@@ -58,15 +60,15 @@ public IFacilityReflectionBuilder AddExtensionsFrom(Action<IFacilityExtensionRef
5860
_extensionsConfig(extensionReflectionBuilder);
5961
}
6062

61-
ReadOnlyCollection<IFacilityExtension<IFacility>> emptyFacilityExtensions =
62-
new List<IFacilityExtension<IFacility>>().AsReadOnly();
63+
ReadOnlyCollection<IFacilityExtension> emptyFacilityExtensions =
64+
new List<IFacilityExtension>().AsReadOnly();
6365

64-
List<(IFacility Facility, IReadOnlyCollection<IFacilityExtension<IFacility>> FacilityExtensions)> result =
66+
List<(IFacility Facility, IReadOnlyCollection<IFacilityExtension> FacilityExtensions)> result =
6567
new();
6668

6769
foreach (IFacility facility in facilities)
6870
{
69-
IReadOnlyCollection<IFacilityExtension<IFacility>> facilityExtensions =
71+
IReadOnlyCollection<IFacilityExtension> facilityExtensions =
7072
extensionReflectionBuilder?.Resolve(facility.GetType())
7173
?? emptyFacilityExtensions;
7274

DependencyInjection/src/AppCoreNet.Extensions.DependencyInjection.Abstractions/Facilities/IFacilityExtension.cs

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,20 @@ namespace AppCoreNet.Extensions.DependencyInjection.Facilities;
88
/// <summary>
99
/// Represents an extension for a facility.
1010
/// </summary>
11-
/// <typeparam name="T">The type of the facility.</typeparam>
12-
public interface IFacilityExtension<in T>
13-
where T : IFacility
11+
public interface IFacilityExtension
1412
{
1513
/// <summary>
1614
/// Must be implemented to register services with the <see cref="IServiceCollection"/>.
1715
/// </summary>
1816
/// <param name="services">The <see cref="IServiceCollection"/>.</param>
1917
void ConfigureServices(IServiceCollection services);
18+
}
19+
20+
/// <summary>
21+
/// Represents an extension for a facility.
22+
/// </summary>
23+
/// <typeparam name="T">The type of the facility.</typeparam>
24+
public interface IFacilityExtension<in T> : IFacilityExtension
25+
where T : IFacility
26+
{
2027
}

DependencyInjection/src/AppCoreNet.Extensions.DependencyInjection.Abstractions/Facilities/IFacilityExtensionReflectionBuilder.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
using System;
55
using System.ComponentModel;
6+
using System.Diagnostics.CodeAnalysis;
67

78
namespace AppCoreNet.Extensions.DependencyInjection.Facilities;
89

@@ -27,6 +28,7 @@ public interface IFacilityExtensionReflectionBuilder
2728
/// <param name="configure">The configuration delegate.</param>
2829
/// <returns>The <see cref="IFacilityExtensionReflectionBuilder"/> to allow chaining.</returns>
2930
[EditorBrowsable(EditorBrowsableState.Advanced)]
30-
public IFacilityExtensionReflectionBuilder AddResolver<T>(Action<T>? configure = null)
31+
public IFacilityExtensionReflectionBuilder AddResolver<
32+
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] T>(Action<T>? configure = null)
3133
where T : IFacilityExtensionResolver;
3234
}

DependencyInjection/src/AppCoreNet.Extensions.DependencyInjection.Abstractions/Facilities/IFacilityExtensionResolver.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,5 +17,5 @@ public interface IFacilityExtensionResolver
1717
/// <param name="facilityType">The type of the facility.</param>
1818
/// <returns>The <see cref="IEnumerable{T}"/> of facility extensions.</returns>
1919
/// <exception cref="ArgumentNullException">Argument <paramref name="facilityType"/> is null.</exception>
20-
IEnumerable<IFacilityExtension<IFacility>> Resolve(Type facilityType);
20+
IEnumerable<IFacilityExtension> Resolve(Type facilityType);
2121
}

DependencyInjection/src/AppCoreNet.Extensions.DependencyInjection.Abstractions/Facilities/IFacilityReflectionBuilder.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
using System;
55
using System.ComponentModel;
6+
using System.Diagnostics.CodeAnalysis;
67

78
namespace AppCoreNet.Extensions.DependencyInjection.Facilities;
89

@@ -27,7 +28,8 @@ public interface IFacilityReflectionBuilder
2728
/// <param name="configure">The configuration delegate.</param>
2829
/// <returns>The <see cref="IFacilityReflectionBuilder"/> to allow chaining.</returns>
2930
[EditorBrowsable(EditorBrowsableState.Advanced)]
30-
public IFacilityReflectionBuilder AddResolver<T>(Action<T>? configure = null)
31+
public IFacilityReflectionBuilder AddResolver<
32+
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] T>(Action<T>? configure = null)
3133
where T : IFacilityResolver;
3234

3335
/// <summary>

DependencyInjection/src/AppCoreNet.Extensions.DependencyInjection.Abstractions/FacilityServiceCollectionExtensions.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -104,14 +104,14 @@ public static IServiceCollection AddFacilitiesFrom(
104104

105105
configure(builder);
106106

107-
IReadOnlyCollection<(IFacility Facility, IReadOnlyCollection<IFacilityExtension<IFacility>> FacilityExtensions)>
107+
IReadOnlyCollection<(IFacility Facility, IReadOnlyCollection<IFacilityExtension> FacilityExtensions)>
108108
facilities = builder.Resolve();
109109

110-
foreach ((IFacility Facility, IReadOnlyCollection<IFacilityExtension<IFacility>> FacilityExtensions) item in facilities)
110+
foreach ((IFacility Facility, IReadOnlyCollection<IFacilityExtension> FacilityExtensions) item in facilities)
111111
{
112112
item.Facility.ConfigureServices(services);
113113

114-
foreach (IFacilityExtension<IFacility> facilityExtension in item.FacilityExtensions)
114+
foreach (IFacilityExtension facilityExtension in item.FacilityExtensions)
115115
{
116116
facilityExtension.ConfigureServices(services);
117117
}

0 commit comments

Comments
 (0)