11using System ;
22using Unity ;
3+ using Unity . Injection ;
34using Unity . Lifetime ;
4- using Unity . Registration ;
55
66namespace LazyProxy . Unity
77{
@@ -10,7 +10,8 @@ namespace LazyProxy.Unity
1010 /// </summary>
1111 public static class UnityExtensions
1212 {
13- private static readonly Func < LifetimeManager > GetTransientLifetimeManager = ( ) => new TransientLifetimeManager ( ) ;
13+ private static readonly Func < ITypeLifetimeManager > GetTransientLifetimeManager =
14+ ( ) => new TransientLifetimeManager ( ) ;
1415
1516 /// <summary>
1617 /// Is used to register interface TFrom to class TTo by creation a lazy proxy at runtime.
@@ -53,7 +54,7 @@ public static IUnityContainer RegisterLazy<TFrom, TTo>(this IUnityContainer cont
5354 /// <typeparam name="TTo">The binded class.</typeparam>
5455 /// <returns>The instance of Unity container.</returns>
5556 public static IUnityContainer RegisterLazy < TFrom , TTo > ( this IUnityContainer container ,
56- Func < LifetimeManager > getLifetimeManager ,
57+ Func < ITypeLifetimeManager > getLifetimeManager ,
5758 params InjectionMember [ ] injectionMembers )
5859 where TTo : TFrom where TFrom : class =>
5960 container . RegisterLazy < TFrom , TTo > ( null , getLifetimeManager , injectionMembers ) ;
@@ -71,7 +72,7 @@ public static IUnityContainer RegisterLazy<TFrom, TTo>(this IUnityContainer cont
7172 /// <returns>The instance of Unity container.</returns>
7273 public static IUnityContainer RegisterLazy < TFrom , TTo > ( this IUnityContainer container ,
7374 string name ,
74- Func < LifetimeManager > getLifetimeManager ,
75+ Func < ITypeLifetimeManager > getLifetimeManager ,
7576 params InjectionMember [ ] injectionMembers )
7677 where TTo : TFrom where TFrom : class =>
7778 container . RegisterLazy ( typeof ( TFrom ) , typeof ( TTo ) , name , getLifetimeManager , injectionMembers ) ;
@@ -121,7 +122,7 @@ public static IUnityContainer RegisterLazy(this IUnityContainer container,
121122 public static IUnityContainer RegisterLazy ( this IUnityContainer container ,
122123 Type typeFrom ,
123124 Type typeTo ,
124- Func < LifetimeManager > getLifetimeManager ,
125+ Func < ITypeLifetimeManager > getLifetimeManager ,
125126 params InjectionMember [ ] injectionMembers ) =>
126127 container . RegisterLazy ( typeFrom , typeTo , null , getLifetimeManager , injectionMembers ) ;
127128
@@ -140,7 +141,7 @@ public static IUnityContainer RegisterLazy(this IUnityContainer container,
140141 Type typeFrom ,
141142 Type typeTo ,
142143 string name ,
143- Func < LifetimeManager > getLifetimeManager ,
144+ Func < ITypeLifetimeManager > getLifetimeManager ,
144145 params InjectionMember [ ] injectionMembers )
145146 {
146147 // There is no way to constraint it on the compilation step.
@@ -149,12 +150,42 @@ public static IUnityContainer RegisterLazy(this IUnityContainer container,
149150 throw new NotSupportedException ( "The lazy registration is supported only for interfaces." ) ;
150151 }
151152
152- var registrationName = Guid . NewGuid ( ) . ToString ( ) ;
153+ // Note #1
154+ // -------
155+ // If UnityContainer has the correct overload of the '.RegisterFactory' method we can make it easier:
156+ //
157+ // var registrationName = Guid.NewGuid().ToString();
158+ // return container
159+ // .RegisterType(typeFrom, typeTo, registrationName, getLifetimeManager(), injectionMembers)
160+ // .RegisterFactory(typeFrom, name,
161+ // (c, t, n, o) => LazyProxyBuilder.CreateInstance(t, () => c.Resolve(t, registrationName, o)),
162+ // getLifetimeManager());
163+ //
164+ // We opened an issue on GitHub and suggested pull requests to introduce the overload:
165+ // - https://github.com/unitycontainer/container/issues/147
166+ // - https://github.com/unitycontainer/abstractions/pull/98
167+ // - https://github.com/unitycontainer/container/pull/148
168+ //
169+ // But unfortunately the issue and pull requests were rejected for reasons not entirely clear.
170+ // That is why we have to use extension.
171+ //
172+ // Note #2
173+ // -------
174+ // We have to use an extension per type because UnityContainer has weird behaviour when work with
175+ // open generic types therefore we can't use fake interface to avoid multiple extensions:
176+ //
177+ // public interface ILazyProxy<T> {}
178+ //
179+ // ...then register types like this:
180+ // container.Register(_typeFrom, _typeTo, "LazyProxyImpl" + _name);
181+ // container.Register(_typeFrom, typeof(ILazyProxy<>).MakeGenericType(_typeFrom), _name);
182+ //
183+ // ...and use single extension per container:
184+ // context.Policy.Set(typeof(ILazyProxy<>), ...)
153185
154- return container
155- . RegisterType ( typeFrom , typeTo , registrationName , getLifetimeManager ( ) , injectionMembers )
156- . RegisterType ( typeFrom , name , getLifetimeManager ( ) , new UnityInjectionFactory (
157- ( c , t , n , o ) => LazyProxyBuilder . CreateInstance ( t , ( ) => c . Resolve ( t , registrationName , o ) ) ) ) ;
186+ return container . AddExtension (
187+ new LazyProxyUnityExtension ( typeFrom , typeTo , name , getLifetimeManager , injectionMembers )
188+ ) ;
158189 }
159190 }
160191}
0 commit comments