1
1
using System ;
2
2
using System . Collections . Generic ;
3
- using System . Linq ;
4
- using System . Reflection ;
5
3
using Autofac ;
6
4
using Autofac . Builder ;
7
5
using Autofac . Core ;
8
- using Autofac . Core . Activators . Delegate ;
6
+ using Autofac . Features . OpenGenerics ;
9
7
10
8
namespace LazyProxy . Autofac
11
9
{
@@ -14,27 +12,8 @@ namespace LazyProxy.Autofac
14
12
/// </summary>
15
13
public static class AutofacExtensions
16
14
{
17
- private static readonly ConstructorInfo RegistrationBuilderConstructor ;
18
-
19
- static AutofacExtensions ( )
20
- {
21
- // There is no way to create RegistrationBuilder with TypedService / KeyedService without reflection.
22
- RegistrationBuilderConstructor = typeof ( ILifetimeScope ) . Assembly
23
- . GetType ( "Autofac.Builder.RegistrationBuilder`3" )
24
- . MakeGenericType (
25
- typeof ( object ) ,
26
- typeof ( SimpleActivatorData ) ,
27
- typeof ( SingleRegistrationStyle ) )
28
- . GetConstructor ( new [ ]
29
- {
30
- typeof ( Service ) ,
31
- typeof ( SimpleActivatorData ) ,
32
- typeof ( SingleRegistrationStyle )
33
- } ) ;
34
- }
35
-
36
15
/// <summary>
37
- /// Is used to register interface TFrom to class TTo by creation a lazy proxy at runtime.
16
+ /// Is used to register non open generic interface TFrom to class TTo by creation a lazy proxy at runtime.
38
17
/// The real class To will be instantiated only after first method or property execution.
39
18
/// </summary>
40
19
/// <param name="builder">The instance of the Autofac container builder.</param>
@@ -50,7 +29,7 @@ public static IRegistrationBuilder<object, SimpleActivatorData, SingleRegistrati
50
29
builder . RegisterLazy ( typeof ( TFrom ) , typeof ( TTo ) , name , nonLazyRegistrationMutator ) ;
51
30
52
31
/// <summary>
53
- /// Is used to register interface TFrom to class TTo by creation a lazy proxy at runtime.
32
+ /// Is used to register non open generic interface TFrom to class TTo by creation a lazy proxy at runtime.
54
33
/// The real class To will be instantiated only after first method or property execution.
55
34
/// </summary>
56
35
/// <param name="typeFrom">The linked interface.</param>
@@ -66,73 +45,68 @@ public static IRegistrationBuilder<object, SimpleActivatorData, SingleRegistrati
66
45
// There is no way to constraint it on the compilation step.
67
46
if ( ! typeFrom . IsInterface )
68
47
{
69
- throw new NotSupportedException ( "The lazy registration is supported only for interfaces." ) ;
48
+ throw new NotSupportedException (
49
+ "The lazy registration is supported only for interfaces." ) ;
70
50
}
71
51
72
- var registrationName = Guid . NewGuid ( ) . ToString ( ) ;
73
- IRegistrationBuilder < object , SimpleActivatorData , SingleRegistrationStyle > registration ;
74
-
75
52
if ( typeTo . IsGenericTypeDefinition )
76
53
{
77
- var nonLazyRegistration = builder . RegisterGeneric ( typeTo ) . Named ( registrationName , typeFrom ) ;
78
- nonLazyRegistrationMutator ? . Mutate ( nonLazyRegistration ) ;
79
-
80
- registration = builder . RegisterGenericFactory ( typeFrom , name ,
81
- ( c , t , n , p ) => CreateLazyProxy ( c , t , registrationName , p ) ) ;
54
+ throw new ArgumentException (
55
+ $ "{ typeFrom } is an open generic type definition. Use the 'RegisterGenericLazy' method instead.") ;
82
56
}
83
- else
84
- {
85
- var nonLazyRegistration = builder . RegisterType ( typeTo ) . Named ( registrationName , typeFrom ) ;
86
- nonLazyRegistrationMutator ? . Mutate ( nonLazyRegistration ) ;
87
57
88
- registration = builder . Register (
89
- ( c , p ) => CreateLazyProxy ( c . Resolve < IComponentContext > ( ) , typeFrom , registrationName , p ) ) ;
90
- }
58
+ var registrationName = Guid . NewGuid ( ) . ToString ( ) ;
59
+ var nonLazyRegistration = builder . RegisterType ( typeTo ) . Named ( registrationName , typeFrom ) ;
60
+ nonLazyRegistrationMutator ? . Mutate ( nonLazyRegistration ) ;
61
+
62
+ var registration = builder . Register ( ( c , p ) =>
63
+ CreateLazyProxy ( c . Resolve < IComponentContext > ( ) , typeFrom , registrationName , p ) ) ;
91
64
92
65
return name == null
93
66
? registration . As ( typeFrom )
94
67
: registration . Named ( name , typeFrom ) ;
95
68
}
96
69
97
70
/// <summary>
98
- /// Registers a delegate as a component for open generic types.
71
+ /// Is used to register open generic interface TFrom to class TTo by creation a lazy proxy at runtime.
72
+ /// The real class To will be instantiated only after first method or property execution.
99
73
/// </summary>
74
+ /// <param name="typeFrom">The linked interface.</param>
75
+ /// <param name="typeTo">The linked class.</param>
100
76
/// <param name="builder">The instance of the Autofac container builder.</param>
101
- /// <param name="type"><see cref="Type"/> of the registered component.</param>
102
- /// <param name="name">Name of the registered component.</param>
103
- /// <param name="factory">The delegate to register.</param>
104
- /// <returns>Registration builder allowing the registration to be configured.</returns>
105
- public static IRegistrationBuilder < object , SimpleActivatorData , SingleRegistrationStyle >
106
- RegisterGenericFactory ( this ContainerBuilder builder , Type type , string name ,
107
- Func < IComponentContext , Type , string , Parameter [ ] , object > factory )
77
+ /// <param name="name">The registration name. Null if named registration is not required.</param>
78
+ /// <param name="nonLazyRegistrationMutator">A mutator allowing to change the non-lazy registration.</param>
79
+ /// <returns>The instance of the Autofac registration builder.</returns>
80
+ public static IRegistrationBuilder < object , OpenGenericDelegateActivatorData , DynamicRegistrationStyle >
81
+ RegisterGenericLazy ( this ContainerBuilder builder , Type typeFrom , Type typeTo , string name = null ,
82
+ IRegistrationMutator nonLazyRegistrationMutator = null )
108
83
{
109
- var registration = ( IRegistrationBuilder < object , SimpleActivatorData , SingleRegistrationStyle > )
110
- RegistrationBuilderConstructor . Invoke ( new [ ]
111
- {
112
- string . IsNullOrEmpty ( name )
113
- ? ( object ) new TypedService ( type )
114
- : new KeyedService ( name , type ) ,
115
-
116
- new SimpleActivatorData ( new DelegateActivator ( type ,
117
- ( c , p ) =>
118
- {
119
- var parameters = p . ToArray ( ) ;
120
- var serviceType = parameters . Named < Type > ( OpenGenericFactoryRegistrationSource . ServiceType ) ;
121
- var context = c . Resolve < IComponentContext > ( ) ;
84
+ // There is no way to constraint it on the compilation step.
85
+ if ( ! typeFrom . IsInterface )
86
+ {
87
+ throw new NotSupportedException (
88
+ "The lazy registration is supported only for interfaces." ) ;
89
+ }
122
90
123
- return factory ( context , serviceType , name , parameters ) ;
124
- } ) ) ,
91
+ if ( ! typeTo . IsGenericTypeDefinition )
92
+ {
93
+ throw new ArgumentException (
94
+ $ "{ typeFrom } is not an open generic type definition. Use the 'RegisterLazy' method instead.") ;
95
+ }
125
96
126
- new SingleRegistrationStyle ( )
127
- } ) ;
97
+ var registrationName = Guid . NewGuid ( ) . ToString ( ) ;
98
+ var nonLazyRegistration = builder . RegisterGeneric ( typeTo ) . Named ( registrationName , typeFrom ) ;
99
+ nonLazyRegistrationMutator ? . Mutate ( nonLazyRegistration ) ;
128
100
129
- registration . RegistrationData . DeferredCallback = builder . RegisterCallback (
130
- cr => cr . AddRegistrationSource (
131
- new OpenGenericFactoryRegistrationSource (
132
- registration . RegistrationData ,
133
- registration . ActivatorData ) ) ) ;
101
+ var registration = builder . RegisterGeneric ( ( c , t , p ) =>
102
+ {
103
+ var closedTypeFrom = typeFrom . MakeGenericType ( t ) ;
104
+ return CreateLazyProxy ( c . Resolve < IComponentContext > ( ) , closedTypeFrom , registrationName , p ) ;
105
+ } ) ;
134
106
135
- return registration ;
107
+ return name == null
108
+ ? registration . As ( typeFrom )
109
+ : registration . Named ( name , typeFrom ) ;
136
110
}
137
111
138
112
private static object CreateLazyProxy (
0 commit comments