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,28 +12,9 @@ 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.
38
- /// The real class To will be instantiated only after first method or property execution.
16
+ /// Registers a mapping of a non-open generic interface TFrom to the class TTo via run-time generated lazy
17
+ /// proxy type. The real class TTo 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>
41
20
/// <param name="name">The registration name. Null if named registration is not required.</param>
@@ -50,8 +29,8 @@ 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.
54
- /// The real class To will be instantiated only after first method or property execution.
32
+ /// Registers a mapping of a non-open generic interface TFrom to the class TTo via run-time generated lazy
33
+ /// proxy type. The real class TTo will be instantiated only after first method or property execution.
55
34
/// </summary>
56
35
/// <param name="typeFrom">The linked interface.</param>
57
36
/// <param name="typeTo">The linked class.</param>
@@ -63,76 +42,69 @@ public static IRegistrationBuilder<object, SimpleActivatorData, SingleRegistrati
63
42
RegisterLazy ( this ContainerBuilder builder , Type typeFrom , Type typeTo , string name = null ,
64
43
IRegistrationMutator nonLazyRegistrationMutator = null )
65
44
{
66
- // There is no way to constraint it on the compilation step.
67
45
if ( ! typeFrom . IsInterface )
68
46
{
69
- throw new NotSupportedException ( "The lazy registration is supported only for interfaces." ) ;
47
+ throw new NotSupportedException (
48
+ "The lazy registration is supported only for interfaces." ) ;
70
49
}
71
50
72
- var registrationName = Guid . NewGuid ( ) . ToString ( ) ;
73
- IRegistrationBuilder < object , SimpleActivatorData , SingleRegistrationStyle > registration ;
74
-
75
51
if ( typeTo . IsGenericTypeDefinition )
76
52
{
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 ) ) ;
53
+ throw new ArgumentException (
54
+ $ "{ typeFrom } is an open generic type definition. Use the 'RegisterGenericLazy' method instead.") ;
82
55
}
83
- else
84
- {
85
- var nonLazyRegistration = builder . RegisterType ( typeTo ) . Named ( registrationName , typeFrom ) ;
86
- nonLazyRegistrationMutator ? . Mutate ( nonLazyRegistration ) ;
87
56
88
- registration = builder . Register (
89
- ( c , p ) => CreateLazyProxy ( c . Resolve < IComponentContext > ( ) , typeFrom , registrationName , p ) ) ;
90
- }
57
+ var registrationName = Guid . NewGuid ( ) . ToString ( ) ;
58
+ var nonLazyRegistration = builder . RegisterType ( typeTo ) . Named ( registrationName , typeFrom ) ;
59
+ nonLazyRegistrationMutator ? . Mutate ( nonLazyRegistration ) ;
60
+
61
+ var registration = builder . Register ( ( c , p ) =>
62
+ CreateLazyProxy ( c . Resolve < IComponentContext > ( ) , typeFrom , registrationName , p ) ) ;
91
63
92
64
return name == null
93
65
? registration . As ( typeFrom )
94
66
: registration . Named ( name , typeFrom ) ;
95
67
}
96
68
97
69
/// <summary>
98
- /// Registers a delegate as a component for open generic types.
70
+ /// Registers a mapping of an open generic interface TFrom to the class TTo via run-time generated lazy
71
+ /// proxy type. The real class TTo will be instantiated only after first method or property execution.
99
72
/// </summary>
73
+ /// <param name="typeFrom">The linked interface.</param>
74
+ /// <param name="typeTo">The linked class.</param>
100
75
/// <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 )
76
+ /// <param name="name">The registration name. Null if named registration is not required.</param>
77
+ /// <param name="nonLazyRegistrationMutator">A mutator allowing to change the non-lazy registration.</param>
78
+ /// <returns>The instance of the Autofac registration builder.</returns>
79
+ public static IRegistrationBuilder < object , OpenGenericDelegateActivatorData , DynamicRegistrationStyle >
80
+ RegisterGenericLazy ( this ContainerBuilder builder , Type typeFrom , Type typeTo , string name = null ,
81
+ IRegistrationMutator nonLazyRegistrationMutator = null )
108
82
{
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 > ( ) ;
83
+ if ( ! typeFrom . IsInterface )
84
+ {
85
+ throw new NotSupportedException (
86
+ "The lazy registration is supported only for interfaces." ) ;
87
+ }
122
88
123
- return factory ( context , serviceType , name , parameters ) ;
124
- } ) ) ,
89
+ if ( ! typeTo . IsGenericTypeDefinition )
90
+ {
91
+ throw new ArgumentException (
92
+ $ "{ typeFrom } is not an open generic type definition. Use the 'RegisterLazy' method instead.") ;
93
+ }
125
94
126
- new SingleRegistrationStyle ( )
127
- } ) ;
95
+ var registrationName = Guid . NewGuid ( ) . ToString ( ) ;
96
+ var nonLazyRegistration = builder . RegisterGeneric ( typeTo ) . Named ( registrationName , typeFrom ) ;
97
+ nonLazyRegistrationMutator ? . Mutate ( nonLazyRegistration ) ;
128
98
129
- registration . RegistrationData . DeferredCallback = builder . RegisterCallback (
130
- cr => cr . AddRegistrationSource (
131
- new OpenGenericFactoryRegistrationSource (
132
- registration . RegistrationData ,
133
- registration . ActivatorData ) ) ) ;
99
+ var registration = builder . RegisterGeneric ( ( c , t , p ) =>
100
+ {
101
+ var closedTypeFrom = typeFrom . MakeGenericType ( t ) ;
102
+ return CreateLazyProxy ( c . Resolve < IComponentContext > ( ) , closedTypeFrom , registrationName , p ) ;
103
+ } ) ;
134
104
135
- return registration ;
105
+ return name == null
106
+ ? registration . As ( typeFrom )
107
+ : registration . Named ( name , typeFrom ) ;
136
108
}
137
109
138
110
private static object CreateLazyProxy (
0 commit comments