Skip to content

Commit a29f328

Browse files
Revert "Update Autofac to 6.0.0"
This reverts commit 4eace2a.
1 parent 4eace2a commit a29f328

File tree

5 files changed

+268
-100
lines changed

5 files changed

+268
-100
lines changed

LazyProxy.Autofac.Tests/AutofacExtensionTests.cs

Lines changed: 89 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -19,34 +19,8 @@ public class AutofacExtensionTests
1919
[Theory]
2020
[InlineData(null)]
2121
[InlineData("name")]
22-
public void RegisterLazyMustThrowNotSupportedExceptionForNonInterfaces(string name) =>
23-
Assert.Throws<NotSupportedException>(() =>
24-
new ContainerBuilder().RegisterLazy<Service1, Service1>(name));
25-
26-
[Theory]
27-
[InlineData(null)]
28-
[InlineData("name")]
29-
public void RegisterGenericLazyMustThrowNotSupportedExceptionForNonInterfaces(string name) =>
30-
Assert.Throws<NotSupportedException>(() =>
31-
new ContainerBuilder().RegisterGenericLazy(
32-
typeof(GenericService<,,>),
33-
typeof(GenericService<,,>), name));
34-
35-
[Theory]
36-
[InlineData(null)]
37-
[InlineData("name")]
38-
public void RegisterLazyMustThrowArgumentExceptionForOpenGenericInterface(string name) =>
39-
Assert.Throws<ArgumentException>(() =>
40-
new ContainerBuilder().RegisterLazy(
41-
typeof(IGenericService<,,>),
42-
typeof(GenericService<,,>), name));
43-
44-
[Theory]
45-
[InlineData(null)]
46-
[InlineData("name")]
47-
public void RegisterGenericLazyMustThrowArgumentExceptionForNonOpenGenericInterface(string name) =>
48-
Assert.Throws<ArgumentException>(() =>
49-
new ContainerBuilder().RegisterGenericLazy(typeof(IService1), typeof(Service1), name));
22+
public void RegistrationMustThrowNotSupportedExceptionForNonInterfaces(string name) =>
23+
Assert.Throws<NotSupportedException>(() => new ContainerBuilder().RegisterLazy<Service1, Service1>(name));
5024

5125
[Theory]
5226
[InlineData(null)]
@@ -361,7 +335,7 @@ public void ClosedGenericServiceMustBeResolved(string name)
361335
public void OpenGenericServiceMustBeResolved(string name)
362336
{
363337
var containerBuilder = new ContainerBuilder();
364-
containerBuilder.RegisterGenericLazy(typeof(IGenericService<,,>), typeof(GenericService<,,>), name);
338+
containerBuilder.RegisterLazy(typeof(IGenericService<,,>), typeof(GenericService<,,>), name);
365339

366340
using (var container = containerBuilder.Build())
367341
{
@@ -409,6 +383,30 @@ public void NonLazyRegistrationMutatorMustBeApplied(string name)
409383
}
410384
}
411385

386+
[Theory]
387+
[InlineData(null)]
388+
[InlineData("name")]
389+
public void RegisterLazyMustNotAddOpenGenericFactoryRegistrationSourceForNonOpenGenericTypes(
390+
string name)
391+
{
392+
var containerBuilder = new ContainerBuilder();
393+
394+
containerBuilder.RegisterLazy(typeof(IService1), typeof(Service1), name);
395+
396+
containerBuilder.RegisterLazy(
397+
typeof(IGenericService<ParameterType1, ParameterType2, ParameterType3>),
398+
typeof(GenericService<ParameterType1, ParameterType2, ParameterType3>), name);
399+
400+
using (var container = containerBuilder.Build())
401+
{
402+
var count = container.ComponentRegistry.Sources
403+
.OfType<OpenGenericFactoryRegistrationSource>()
404+
.Count();
405+
406+
Assert.Equal(0, count);
407+
}
408+
}
409+
412410
#region Lifetime tests
413411

414412
[Theory]
@@ -461,6 +459,58 @@ public void InstancePerDependencyServiceLifetimeMustBeActualForOpenGenericServic
461459

462460
#endregion
463461

462+
#region RegisterGenericFactory tests
463+
464+
[Theory]
465+
[InlineData(null)]
466+
[InlineData("name")]
467+
public void RegisterGenericFactoryMustBeCorrect(string name)
468+
{
469+
void Test<T>() where T : IGenericService<ParameterType1, ParameterType2, ParameterType3>
470+
{
471+
var parameters = new Parameter[]
472+
{
473+
new NamedParameter("key1", "value1"),
474+
new NamedParameter("key2", "value2")
475+
};
476+
477+
var containerBuilder = new ContainerBuilder();
478+
containerBuilder.RegisterGenericFactory(typeof(T).GetGenericTypeDefinition(), name,
479+
(c, t, n, p) =>
480+
{
481+
Assert.Same(typeof(T), t);
482+
Assert.Same(name, n);
483+
484+
foreach (var parameter in parameters)
485+
{
486+
Assert.Contains(parameter, p);
487+
}
488+
489+
return new GenericService<ParameterType1, ParameterType2, ParameterType3>();
490+
});
491+
492+
using (var container = containerBuilder.Build())
493+
{
494+
var service = name == null
495+
? container.Resolve<T>(parameters)
496+
: container.ResolveNamed<T>(name, parameters);
497+
498+
var result = service.Get(new ParameterType1(), new ParameterType2(), 42);
499+
500+
Assert.Equal(
501+
$"{typeof(ParameterType1).Name}_" +
502+
$"{typeof(ParameterType2).Name}_" +
503+
$"{typeof(int).Name}",
504+
result.Value);
505+
}
506+
}
507+
508+
Test<IGenericService<ParameterType1, ParameterType2, ParameterType3>>();
509+
Test<GenericService<ParameterType1, ParameterType2, ParameterType3>>();
510+
}
511+
512+
#endregion
513+
464514
#region Private members
465515

466516
[ThreadStatic] private static string _service1Id;
@@ -511,14 +561,7 @@ private IEnumerable<Guid> All()
511561
private static void AssertSingleInstanceServiceLifetimeMustBeActual<T>(Type typeFrom, Type typeTo, string name)
512562
{
513563
var containerBuilder = new ContainerBuilder();
514-
if (typeFrom.IsGenericTypeDefinition)
515-
{
516-
containerBuilder.RegisterGenericLazy(typeFrom, typeTo, name).SingleInstance();
517-
}
518-
else
519-
{
520-
containerBuilder.RegisterLazy(typeFrom, typeTo, name).SingleInstance();
521-
}
564+
containerBuilder.RegisterLazy(typeFrom, typeTo, name).SingleInstance();
522565

523566
using (var container = containerBuilder.Build())
524567
{
@@ -542,14 +585,7 @@ private static void AssertInstancePerLifetimeScopeServiceLifetimeMustBeActual<T>
542585
Type typeFrom, Type typeTo, string name)
543586
{
544587
var containerBuilder = new ContainerBuilder();
545-
if (typeFrom.IsGenericTypeDefinition)
546-
{
547-
containerBuilder.RegisterGenericLazy(typeFrom, typeTo, name).InstancePerLifetimeScope();
548-
}
549-
else
550-
{
551-
containerBuilder.RegisterLazy(typeFrom, typeTo, name).InstancePerLifetimeScope();
552-
}
588+
containerBuilder.RegisterLazy(typeFrom, typeTo, name).InstancePerLifetimeScope();
553589

554590
using (var container = containerBuilder.Build())
555591
{
@@ -582,14 +618,7 @@ private static void AssertInstancePerDependencyServiceLifetimeMustBeActual<T>(
582618
Type typeFrom, Type typeTo, string name)
583619
{
584620
var containerBuilder = new ContainerBuilder();
585-
if (typeFrom.IsGenericTypeDefinition)
586-
{
587-
containerBuilder.RegisterGenericLazy(typeFrom, typeTo, name).InstancePerDependency();
588-
}
589-
else
590-
{
591-
containerBuilder.RegisterLazy(typeFrom, typeTo, name).InstancePerDependency();
592-
}
621+
containerBuilder.RegisterLazy(typeFrom, typeTo, name).InstancePerDependency();
593622

594623
using (var container = containerBuilder.Build())
595624
{
@@ -837,6 +866,13 @@ public GenericService()
837866
}
838867
}
839868

869+
// ReSharper disable once MemberCanBePrivate.Global
870+
public interface IGenericService2<T>
871+
{
872+
// ReSharper disable once UnusedMember.Global
873+
T Get(T arg1);
874+
}
875+
840876
#endregion
841877
}
842878
}

LazyProxy.Autofac.Tests/LazyProxy.Autofac.Tests.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
</PropertyGroup>
77

88
<ItemGroup>
9-
<PackageReference Include="Autofac.Extras.DynamicProxy" Version="6.0.0" />
9+
<PackageReference Include="Autofac.Extras.DynamicProxy" Version="5.0.0" />
1010
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.6.0" />
1111
<PackageReference Include="Moq" Version="4.9.0" />
1212
<PackageReference Include="xunit" Version="2.3.1" />

LazyProxy.Autofac/AutofacExtensions.cs

Lines changed: 71 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
using System;
22
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Reflection;
35
using Autofac;
46
using Autofac.Builder;
57
using Autofac.Core;
6-
using Autofac.Features.OpenGenerics;
8+
using Autofac.Core.Activators.Delegate;
79

810
namespace LazyProxy.Autofac
911
{
@@ -12,8 +14,27 @@ namespace LazyProxy.Autofac
1214
/// </summary>
1315
public static class AutofacExtensions
1416
{
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+
1536
/// <summary>
16-
/// Is used to register non open generic interface TFrom to class TTo by creation a lazy proxy at runtime.
37+
/// Is used to register interface TFrom to class TTo by creation a lazy proxy at runtime.
1738
/// The real class To will be instantiated only after first method or property execution.
1839
/// </summary>
1940
/// <param name="builder">The instance of the Autofac container builder.</param>
@@ -29,7 +50,7 @@ public static IRegistrationBuilder<object, SimpleActivatorData, SingleRegistrati
2950
builder.RegisterLazy(typeof(TFrom), typeof(TTo), name, nonLazyRegistrationMutator);
3051

3152
/// <summary>
32-
/// Is used to register non open generic interface TFrom to class TTo by creation a lazy proxy at runtime.
53+
/// Is used to register interface TFrom to class TTo by creation a lazy proxy at runtime.
3354
/// The real class To will be instantiated only after first method or property execution.
3455
/// </summary>
3556
/// <param name="typeFrom">The linked interface.</param>
@@ -45,68 +66,73 @@ public static IRegistrationBuilder<object, SimpleActivatorData, SingleRegistrati
4566
// There is no way to constraint it on the compilation step.
4667
if (!typeFrom.IsInterface)
4768
{
48-
throw new NotSupportedException(
49-
"The lazy registration is supported only for interfaces.");
69+
throw new NotSupportedException("The lazy registration is supported only for interfaces.");
5070
}
5171

72+
var registrationName = Guid.NewGuid().ToString();
73+
IRegistrationBuilder<object, SimpleActivatorData, SingleRegistrationStyle> registration;
74+
5275
if (typeTo.IsGenericTypeDefinition)
5376
{
54-
throw new ArgumentException(
55-
$"{typeFrom} is an open generic type definition. Use the 'RegisterGenericLazy' method instead.");
56-
}
77+
var nonLazyRegistration = builder.RegisterGeneric(typeTo).Named(registrationName, typeFrom);
78+
nonLazyRegistrationMutator?.Mutate(nonLazyRegistration);
5779

58-
var registrationName = Guid.NewGuid().ToString();
59-
var nonLazyRegistration = builder.RegisterType(typeTo).Named(registrationName, typeFrom);
60-
nonLazyRegistrationMutator?.Mutate(nonLazyRegistration);
80+
registration = builder.RegisterGenericFactory(typeFrom, name,
81+
(c, t, n, p) => CreateLazyProxy(c, t, registrationName, p));
82+
}
83+
else
84+
{
85+
var nonLazyRegistration = builder.RegisterType(typeTo).Named(registrationName, typeFrom);
86+
nonLazyRegistrationMutator?.Mutate(nonLazyRegistration);
6187

62-
var registration = builder.Register((c, p) =>
63-
CreateLazyProxy(c.Resolve<IComponentContext>(), typeFrom, registrationName, p));
88+
registration = builder.Register(
89+
(c, p) => CreateLazyProxy(c.Resolve<IComponentContext>(), typeFrom, registrationName, p));
90+
}
6491

6592
return name == null
6693
? registration.As(typeFrom)
6794
: registration.Named(name, typeFrom);
6895
}
6996

7097
/// <summary>
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.
98+
/// Registers a delegate as a component for open generic types.
7399
/// </summary>
74-
/// <param name="typeFrom">The linked interface.</param>
75-
/// <param name="typeTo">The linked class.</param>
76100
/// <param name="builder">The instance of the Autofac container builder.</param>
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)
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)
83108
{
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-
}
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),
90115

91-
if (!typeTo.IsGenericTypeDefinition)
92-
{
93-
throw new ArgumentException(
94-
$"{typeFrom} is not an open generic type definition. Use the 'RegisterLazy' method instead.");
95-
}
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>();
96122

97-
var registrationName = Guid.NewGuid().ToString();
98-
var nonLazyRegistration = builder.RegisterGeneric(typeTo).Named(registrationName, typeFrom);
99-
nonLazyRegistrationMutator?.Mutate(nonLazyRegistration);
123+
return factory(context, serviceType, name, parameters);
124+
})),
100125

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-
});
126+
new SingleRegistrationStyle()
127+
});
106128

107-
return name == null
108-
? registration.As(typeFrom)
109-
: registration.Named(name, typeFrom);
129+
registration.RegistrationData.DeferredCallback = builder.RegisterCallback(
130+
cr => cr.AddRegistrationSource(
131+
new OpenGenericFactoryRegistrationSource(
132+
registration.RegistrationData,
133+
registration.ActivatorData)));
134+
135+
return registration;
110136
}
111137

112138
private static object CreateLazyProxy(

LazyProxy.Autofac/LazyProxy.Autofac.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
</PropertyGroup>
1818

1919
<ItemGroup>
20-
<PackageReference Include="Autofac" Version="6.0.0" />
20+
<PackageReference Include="Autofac" Version="5.2.0" />
2121
<PackageReference Include="LazyProxy" Version="1.0.0" />
2222
</ItemGroup>
2323

0 commit comments

Comments
 (0)