1
+ using System ;
2
+ using System . Collections . Generic ;
3
+ using System . Linq ;
4
+ using System . Reflection ;
5
+ using Unity ;
6
+ using Unity . Builder ;
7
+ using Unity . Injection ;
8
+ using Unity . Policy ;
9
+ using Unity . Registration ;
10
+ using Unity . Resolution ;
11
+
12
+ namespace LazyProxy . Unity
13
+ {
14
+ /// <summary>
15
+ /// A class that lets you specify a factory method the container will use to create the object.
16
+ /// </summary>
17
+ public class UnityInjectionFactory : InjectionMember , IInjectionFactory , IBuildPlanPolicy
18
+ {
19
+ private static readonly FieldInfo ResolverOverrides = typeof ( BuilderContext )
20
+ . GetField ( "_resolverOverrides" , BindingFlags . Instance | BindingFlags . NonPublic ) ;
21
+
22
+ private readonly Func < IUnityContainer , Type , string , ResolverOverride [ ] , object > _factoryFunc ;
23
+
24
+ /// <summary>
25
+ /// Create a new instance of <see cref="UnityInjectionFactory"/> with the given factory function.
26
+ /// </summary>
27
+ /// <param name="factoryFunc">Factory function.</param>
28
+ public UnityInjectionFactory ( Func < IUnityContainer , Type , string , ResolverOverride [ ] , object > factoryFunc )
29
+ {
30
+ _factoryFunc = factoryFunc ?? throw new ArgumentNullException ( nameof ( factoryFunc ) ) ;
31
+ }
32
+
33
+ /// <summary>
34
+ /// Add policies to the policies to configure the container
35
+ /// to call this constructor with the appropriate parameter values.
36
+ /// </summary>
37
+ /// <param name="serviceType">Type of interface being registered. If no interface, this will be null.
38
+ /// This parameter is ignored in this implementation.</param>
39
+ /// <param name="implementationType">Type of concrete type being registered.</param>
40
+ /// <param name="name">Name used to resolve the type object.</param>
41
+ /// <param name="policies">Policy list to add policies to.</param>
42
+ public override void AddPolicies ( Type serviceType , Type implementationType , string name , IPolicyList policies )
43
+ {
44
+ policies . Set ( serviceType , name , typeof ( IBuildPlanPolicy ) , this ) ;
45
+ }
46
+
47
+ /// <summary>
48
+ /// Creates an instance of this build plan's type, or fills in the existing type if passed in.
49
+ /// </summary>
50
+ /// <param name="context">Context used to build up the object.</param>
51
+ /// <exception cref="ArgumentNullException">Context is null.</exception>
52
+ public void BuildUp ( IBuilderContext context )
53
+ {
54
+ if ( context == null )
55
+ throw new ArgumentNullException ( nameof ( context ) ) ;
56
+
57
+ if ( context . Existing != null )
58
+ return ;
59
+
60
+ var resolverOverride = ResolverOverrides . GetValue ( context ) ;
61
+
62
+ var resolverOverrides = resolverOverride == null
63
+ ? new ResolverOverride [ ] { }
64
+ : ( ( IEnumerable < ResolverOverride > ) resolverOverride ) . ToArray ( ) ;
65
+
66
+ var container = context . Container ;
67
+ var type = context . BuildKey . Type ;
68
+ var name = context . BuildKey . Name ;
69
+
70
+ context . Existing = _factoryFunc ( container , type , name , resolverOverrides ) ;
71
+ context . SetPerBuildSingleton ( ) ;
72
+ }
73
+ }
74
+ }
0 commit comments