|
4 | 4 | using System.Reflection; |
5 | 5 | using Microsoft.Extensions.DependencyInjection; |
6 | 6 | using Unity.Injection; |
| 7 | +using Unity.Lifetime; |
7 | 8 |
|
8 | 9 | namespace Unity.Microsoft.DependencyInjection |
9 | 10 | { |
10 | 11 | internal static class Configuration |
11 | 12 | { |
12 | | - static List<Aggregate> _aggregates; |
13 | 13 |
|
14 | | - internal static void Configure(this IUnityContainer container, IServiceCollection services) |
| 14 | + internal static IUnityContainer AddServices(this IUnityContainer container, IServiceCollection services) |
15 | 15 | { |
16 | | - var aggregateTypes = GetAggregateTypes(services); |
| 16 | + var lifetime = container.Configure<MDIExtension>() |
| 17 | + .Lifetime; |
17 | 18 |
|
18 | | - _aggregates = aggregateTypes.Select(t => new Aggregate(t, container)).ToList(); |
19 | | - container.RegisterInstance(_aggregates); |
20 | | - |
21 | | - // Configure all registrations into Unity |
22 | | - foreach (var serviceDescriptor in services) |
| 19 | + foreach (var group in services.GroupBy(serviceDescriptor => serviceDescriptor.ServiceType, |
| 20 | + serviceDescriptor => serviceDescriptor) |
| 21 | + .Select(group => group.ToArray())) |
23 | 22 | { |
24 | | - container.RegisterType(serviceDescriptor, _aggregates); |
25 | | - } |
| 23 | + // Register named types |
| 24 | + for (var i = 0; i < group.Length - 1; i++) |
| 25 | + { |
| 26 | + var descriptor = group[i]; |
| 27 | + container.Register(descriptor, descriptor.GetRegistrationName(), lifetime); |
| 28 | + } |
26 | 29 |
|
27 | | - foreach (var type in _aggregates) |
28 | | - { |
29 | | - type.Register(); |
| 30 | + // Register default types |
| 31 | + container.Register(group[group.Length - 1], null, lifetime); |
30 | 32 | } |
| 33 | + |
| 34 | + return container; |
31 | 35 | } |
32 | 36 |
|
33 | 37 | internal static void Register(this IUnityContainer container, |
34 | | - ServiceDescriptor service, string qualifier) |
| 38 | + ServiceDescriptor serviceDescriptor, string qualifier, ILifetimeContainer lifetime) |
35 | 39 | { |
36 | | - if (service.ImplementationType != null) |
| 40 | + if (serviceDescriptor.ImplementationType != null) |
37 | 41 | { |
38 | | - RegisterImplementation(container, service, qualifier); |
| 42 | + container.RegisterType(serviceDescriptor.ServiceType, |
| 43 | + serviceDescriptor.ImplementationType, |
| 44 | + qualifier, |
| 45 | + serviceDescriptor.GetLifetime(lifetime)); |
39 | 46 | } |
40 | | - else if (service.ImplementationFactory != null) |
| 47 | + else if (serviceDescriptor.ImplementationFactory != null) |
41 | 48 | { |
42 | | - RegisterFactory(container, service, qualifier); |
| 49 | + container.RegisterType(serviceDescriptor.ServiceType, |
| 50 | + qualifier, |
| 51 | + serviceDescriptor.GetLifetime(lifetime), |
| 52 | + new InjectionFactory(scope => |
| 53 | + { |
| 54 | + var serviceProvider = serviceDescriptor.Lifetime == ServiceLifetime.Scoped |
| 55 | + ? scope.Resolve<IServiceProvider>() |
| 56 | + : container.Resolve<IServiceProvider>(); |
| 57 | + var instance = serviceDescriptor.ImplementationFactory(serviceProvider); |
| 58 | + return instance; |
| 59 | + })); |
43 | 60 | } |
44 | | - else if (service.ImplementationInstance != null) |
| 61 | + else if (serviceDescriptor.ImplementationInstance != null) |
45 | 62 | { |
46 | | - RegisterSingleton(container, service, qualifier); |
| 63 | + container.RegisterInstance(serviceDescriptor.ServiceType, |
| 64 | + qualifier, |
| 65 | + serviceDescriptor.ImplementationInstance, |
| 66 | + serviceDescriptor.GetLifetime(lifetime)); |
47 | 67 | } |
48 | 68 | else |
49 | 69 | { |
50 | 70 | throw new InvalidOperationException("Unsupported registration type"); |
51 | 71 | } |
52 | 72 | } |
53 | 73 |
|
54 | | - private static HashSet<Type> GetAggregateTypes(IServiceCollection services) |
55 | | - { |
56 | | - var enumerable = services.GroupBy(serviceDescriptor => serviceDescriptor.ServiceType, |
57 | | - serviceDescriptor => serviceDescriptor) |
58 | | - .Where(typeGrouping => typeGrouping.Count() > 1) |
59 | | - .Select(type => type.Key); |
60 | | - |
61 | | - return new HashSet<Type>(enumerable); |
62 | | - } |
63 | | - |
64 | | - |
65 | | - |
66 | | - private static void RegisterType(this IUnityContainer container, |
67 | | - ServiceDescriptor serviceDescriptor, List<Aggregate> aggregates) |
68 | | - { |
69 | | - var aggregate = aggregates.FirstOrDefault(a => a.Type == serviceDescriptor.ServiceType); |
70 | | - if (aggregate != null) |
71 | | - aggregate.AddService(serviceDescriptor); |
72 | | - else |
73 | | - container.Register(serviceDescriptor, null); |
74 | | - } |
75 | | - |
76 | | - private static void RegisterImplementation(this IUnityContainer container, |
77 | | - ServiceDescriptor serviceDescriptor, string qualifier) |
78 | | - { |
79 | | - container.RegisterType(serviceDescriptor.ServiceType, |
80 | | - serviceDescriptor.ImplementationType, |
81 | | - qualifier, |
82 | | - serviceDescriptor.GetLifetime(container)); |
83 | | - } |
84 | 74 |
|
85 | | - private static void RegisterFactory(this IUnityContainer container, |
86 | | - ServiceDescriptor serviceDescriptor, string qualifier) |
| 75 | + internal static LifetimeManager GetLifetime(this ServiceDescriptor serviceDescriptor, ILifetimeContainer lifetime) |
87 | 76 | { |
88 | | - container.RegisterType(serviceDescriptor.ServiceType, qualifier, serviceDescriptor.GetLifetime(container), |
89 | | - new InjectionFactory(scope => |
90 | | - { |
91 | | - var serviceProvider = serviceDescriptor.Lifetime == ServiceLifetime.Scoped |
92 | | - ? scope.Resolve<IServiceProvider>() |
93 | | - : container.Resolve<IServiceProvider>(); |
94 | | - var instance = serviceDescriptor.ImplementationFactory(serviceProvider); |
95 | | - return instance; |
96 | | - })); |
| 77 | + switch (serviceDescriptor.Lifetime) |
| 78 | + { |
| 79 | + case ServiceLifetime.Scoped: |
| 80 | + return new HierarchicalLifetimeManager(); |
| 81 | + case ServiceLifetime.Singleton: |
| 82 | + return new InjectionSingletonLifetimeManager(lifetime); |
| 83 | + case ServiceLifetime.Transient: |
| 84 | + return new InjectionTransientLifetimeManager(); |
| 85 | + default: |
| 86 | + throw new NotImplementedException( |
| 87 | + $"Unsupported lifetime manager type '{serviceDescriptor.Lifetime}'"); |
| 88 | + } |
97 | 89 | } |
98 | 90 |
|
99 | | - private static void RegisterSingleton(this IUnityContainer container, |
100 | | - ServiceDescriptor serviceDescriptor, string qualifier) |
101 | | - { |
102 | | - container.RegisterInstance(serviceDescriptor.ServiceType, |
103 | | - qualifier, |
104 | | - serviceDescriptor.ImplementationInstance, |
105 | | - serviceDescriptor.GetLifetime(container)); |
106 | | - } |
107 | 91 |
|
108 | 92 | internal static bool CanResolve(this IUnityContainer container, Type type) |
109 | 93 | { |
|
0 commit comments