Skip to content

Commit ca5c931

Browse files
Update to Autofac 6.0.0
1 parent a29f328 commit ca5c931

File tree

5 files changed

+100
-268
lines changed

5 files changed

+100
-268
lines changed

LazyProxy.Autofac.Tests/AutofacExtensionTests.cs

Lines changed: 53 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,34 @@ public class AutofacExtensionTests
1919
[Theory]
2020
[InlineData(null)]
2121
[InlineData("name")]
22-
public void RegistrationMustThrowNotSupportedExceptionForNonInterfaces(string name) =>
23-
Assert.Throws<NotSupportedException>(() => new ContainerBuilder().RegisterLazy<Service1, Service1>(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));
2450

2551
[Theory]
2652
[InlineData(null)]
@@ -335,7 +361,7 @@ public void ClosedGenericServiceMustBeResolved(string name)
335361
public void OpenGenericServiceMustBeResolved(string name)
336362
{
337363
var containerBuilder = new ContainerBuilder();
338-
containerBuilder.RegisterLazy(typeof(IGenericService<,,>), typeof(GenericService<,,>), name);
364+
containerBuilder.RegisterGenericLazy(typeof(IGenericService<,,>), typeof(GenericService<,,>), name);
339365

340366
using (var container = containerBuilder.Build())
341367
{
@@ -383,30 +409,6 @@ public void NonLazyRegistrationMutatorMustBeApplied(string name)
383409
}
384410
}
385411

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-
410412
#region Lifetime tests
411413

412414
[Theory]
@@ -459,58 +461,6 @@ public void InstancePerDependencyServiceLifetimeMustBeActualForOpenGenericServic
459461

460462
#endregion
461463

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-
514464
#region Private members
515465

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

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

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

623594
using (var container = containerBuilder.Build())
624595
{
@@ -866,13 +837,6 @@ public GenericService()
866837
}
867838
}
868839

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-
876840
#endregion
877841
}
878842
}

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="5.0.0" />
9+
<PackageReference Include="Autofac.Extras.DynamicProxy" Version="6.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: 45 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
11
using System;
22
using System.Collections.Generic;
3-
using System.Linq;
4-
using System.Reflection;
53
using Autofac;
64
using Autofac.Builder;
75
using Autofac.Core;
8-
using Autofac.Core.Activators.Delegate;
6+
using Autofac.Features.OpenGenerics;
97

108
namespace LazyProxy.Autofac
119
{
@@ -14,27 +12,8 @@ namespace LazyProxy.Autofac
1412
/// </summary>
1513
public static class AutofacExtensions
1614
{
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-
3615
/// <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.
3817
/// The real class To will be instantiated only after first method or property execution.
3918
/// </summary>
4019
/// <param name="builder">The instance of the Autofac container builder.</param>
@@ -50,7 +29,7 @@ public static IRegistrationBuilder<object, SimpleActivatorData, SingleRegistrati
5029
builder.RegisterLazy(typeof(TFrom), typeof(TTo), name, nonLazyRegistrationMutator);
5130

5231
/// <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.
5433
/// The real class To will be instantiated only after first method or property execution.
5534
/// </summary>
5635
/// <param name="typeFrom">The linked interface.</param>
@@ -66,73 +45,68 @@ public static IRegistrationBuilder<object, SimpleActivatorData, SingleRegistrati
6645
// There is no way to constraint it on the compilation step.
6746
if (!typeFrom.IsInterface)
6847
{
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.");
7050
}
7151

72-
var registrationName = Guid.NewGuid().ToString();
73-
IRegistrationBuilder<object, SimpleActivatorData, SingleRegistrationStyle> registration;
74-
7552
if (typeTo.IsGenericTypeDefinition)
7653
{
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.");
8256
}
83-
else
84-
{
85-
var nonLazyRegistration = builder.RegisterType(typeTo).Named(registrationName, typeFrom);
86-
nonLazyRegistrationMutator?.Mutate(nonLazyRegistration);
8757

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));
9164

9265
return name == null
9366
? registration.As(typeFrom)
9467
: registration.Named(name, typeFrom);
9568
}
9669

9770
/// <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.
9973
/// </summary>
74+
/// <param name="typeFrom">The linked interface.</param>
75+
/// <param name="typeTo">The linked class.</param>
10076
/// <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)
10883
{
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+
}
12290

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+
}
12596

126-
new SingleRegistrationStyle()
127-
});
97+
var registrationName = Guid.NewGuid().ToString();
98+
var nonLazyRegistration = builder.RegisterGeneric(typeTo).Named(registrationName, typeFrom);
99+
nonLazyRegistrationMutator?.Mutate(nonLazyRegistration);
128100

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+
});
134106

135-
return registration;
107+
return name == null
108+
? registration.As(typeFrom)
109+
: registration.Named(name, typeFrom);
136110
}
137111

138112
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="5.2.0" />
20+
<PackageReference Include="Autofac" Version="6.0.0" />
2121
<PackageReference Include="LazyProxy" Version="1.0.0" />
2222
</ItemGroup>
2323

0 commit comments

Comments
 (0)