Skip to content

Commit 079e5e4

Browse files
Merge pull request #7 from servicetitan/migrate-to-unity-5-10
Migrate to UnityContainer v5.10.2
2 parents f0711a6 + 2b17b03 commit 079e5e4

File tree

6 files changed

+111
-89
lines changed

6 files changed

+111
-89
lines changed

LazyProxy.Unity.Sample/LazyProxy.Unity.Sample.csproj

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<TargetFramework>netcoreapp2.0</TargetFramework>
55
</PropertyGroup>
66
<ItemGroup>
7-
<PackageReference Include="Unity" Version="5.8.13" />
7+
<PackageReference Include="Unity" Version="5.10.2" />
88
</ItemGroup>
99
<ItemGroup>
1010
<ProjectReference Include="..\LazyProxy.Unity\LazyProxy.Unity.csproj" />

LazyProxy.Unity.Tests/UnityExtensionTests.cs

+1-2
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,11 @@
22
using System.Runtime.CompilerServices;
33
using Moq;
44
using Unity;
5-
using Unity.Exceptions;
65
using Unity.Injection;
76
using Unity.Lifetime;
87
using Unity.Resolution;
98
using Xunit;
10-
using DependencyAttribute = Unity.Attributes.DependencyAttribute;
9+
using DependencyAttribute = Unity.DependencyAttribute;
1110

1211
[assembly: InternalsVisibleTo("LazyProxy.DynamicTypes")]
1312

LazyProxy.Unity/LazyProxy.Unity.csproj

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,6 @@
1616
</PropertyGroup>
1717
<ItemGroup>
1818
<PackageReference Include="LazyProxy" Version="0.1.4" />
19-
<PackageReference Include="Unity" Version="5.8.13" />
19+
<PackageReference Include="Unity" Version="5.10.2" />
2020
</ItemGroup>
2121
</Project>
+66
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
using System;
2+
using Unity.Builder;
3+
using Unity.Extension;
4+
using Unity.Injection;
5+
using Unity.Lifetime;
6+
using Unity.Policy;
7+
8+
namespace LazyProxy.Unity
9+
{
10+
/// <summary>
11+
/// Allows to add a lazy registration to the container.
12+
/// </summary>
13+
public class LazyProxyUnityExtension : UnityContainerExtension
14+
{
15+
private readonly Type _typeFrom;
16+
private readonly Type _typeTo;
17+
private readonly string _name;
18+
private readonly Func<ITypeLifetimeManager> _getLifetimeManager;
19+
private readonly InjectionMember[] _injectionMembers;
20+
21+
/// <summary>
22+
/// Initialize a new instance of <see cref="LazyProxyUnityExtension"/>.
23+
/// </summary>
24+
/// <param name="typeFrom">The binded interface.</param>
25+
/// <param name="typeTo">The binded class.</param>
26+
/// <param name="name">The registration name.</param>
27+
/// <param name="getLifetimeManager">The function instance lifetime provides.</param>
28+
/// <param name="injectionMembers">The set of injection members.</param>
29+
public LazyProxyUnityExtension(
30+
Type typeFrom,
31+
Type typeTo,
32+
string name,
33+
Func<ITypeLifetimeManager> getLifetimeManager,
34+
params InjectionMember[] injectionMembers)
35+
{
36+
_typeFrom = typeFrom ?? throw new ArgumentNullException(nameof(typeFrom));
37+
_typeTo = typeTo ?? throw new ArgumentNullException(nameof(typeTo));
38+
_name = name;
39+
_getLifetimeManager = getLifetimeManager ?? throw new ArgumentNullException(nameof(getLifetimeManager));
40+
_injectionMembers = injectionMembers;
41+
}
42+
43+
/// <inheritdoc />
44+
protected override void Initialize()
45+
{
46+
var registrationName = Guid.NewGuid().ToString();
47+
48+
Context.Container.RegisterType(_typeFrom, _typeTo, _name, _getLifetimeManager());
49+
Context.Container.RegisterType(_typeFrom, _typeTo, registrationName, _getLifetimeManager(), _injectionMembers);
50+
51+
Context.Policies.Set(_typeFrom, _name, typeof(ResolveDelegateFactory),
52+
(ResolveDelegateFactory) ((ref BuilderContext _) =>
53+
(ref BuilderContext c) =>
54+
{
55+
var container = c.Container;
56+
var type = c.RegistrationType;
57+
var overrides = c.Overrides;
58+
59+
return LazyProxyBuilder.CreateInstance(type,
60+
() => container.Resolve(type, registrationName, overrides)
61+
);
62+
})
63+
);
64+
}
65+
}
66+
}

LazyProxy.Unity/UnityExtensions.cs

+42-11
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
using System;
22
using Unity;
3+
using Unity.Injection;
34
using Unity.Lifetime;
4-
using Unity.Registration;
55

66
namespace 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
}

LazyProxy.Unity/UnityInjectionFactory.cs

-74
This file was deleted.

0 commit comments

Comments
 (0)