Skip to content

Commit 63b979b

Browse files
committed
Increased test coverage.
1 parent e1bb3da commit 63b979b

9 files changed

Lines changed: 338 additions & 18 deletions

File tree

.vscode/settings.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
{
22
"cSpell.words": [
33
"autofac",
4+
"diagnoser",
45
"netstandard",
56
"xunit"
67
],

src/Autofac.Extras.AggregateService/GeneratedAggregateServiceRegistry.cs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -32,14 +32,14 @@ namespace Autofac.Extras.AggregateService;
3232
/// </remarks>
3333
public static class GeneratedAggregateServiceRegistry
3434
{
35-
private static readonly object SyncRoot = new object();
35+
private static readonly object _syncRoot = new object();
3636

3737
// Closed (non-generic, or already-closed generic) interface type -> factory.
38-
private static readonly Dictionary<Type, Func<IComponentContext, object>> ClosedFactories =
38+
private static readonly Dictionary<Type, Func<IComponentContext, object>> _closedFactories =
3939
new Dictionary<Type, Func<IComponentContext, object>>();
4040

4141
// Open generic interface definition -> open generic backing class definition.
42-
private static readonly Dictionary<Type, Type> OpenGenericBackings = new Dictionary<Type, Type>();
42+
private static readonly Dictionary<Type, Type> _openGenericBackings = new Dictionary<Type, Type>();
4343

4444
/// <summary>
4545
/// Registers a generated factory for a closed aggregate service interface
@@ -68,9 +68,9 @@ public static void Register(Type interfaceType, Func<IComponentContext, object>
6868
throw new ArgumentNullException(nameof(factory));
6969
}
7070

71-
lock (SyncRoot)
71+
lock (_syncRoot)
7272
{
73-
ClosedFactories[interfaceType] = factory;
73+
_closedFactories[interfaceType] = factory;
7474
}
7575
}
7676

@@ -101,9 +101,9 @@ public static void RegisterOpenGeneric(Type openInterfaceType, Type openBackingT
101101
throw new ArgumentNullException(nameof(openBackingType));
102102
}
103103

104-
lock (SyncRoot)
104+
lock (_syncRoot)
105105
{
106-
OpenGenericBackings[openInterfaceType] = openBackingType;
106+
_openGenericBackings[openInterfaceType] = openBackingType;
107107
}
108108
}
109109

@@ -133,11 +133,11 @@ internal static bool TryCreate(Type interfaceType, IComponentContext context, [N
133133
Func<IComponentContext, object>? factory = null;
134134
Type? openBacking = null;
135135

136-
lock (SyncRoot)
136+
lock (_syncRoot)
137137
{
138-
if (!ClosedFactories.TryGetValue(interfaceType, out factory) && interfaceType.IsConstructedGenericType)
138+
if (!_closedFactories.TryGetValue(interfaceType, out factory) && interfaceType.IsConstructedGenericType)
139139
{
140-
OpenGenericBackings.TryGetValue(interfaceType.GetGenericTypeDefinition(), out openBacking);
140+
_openGenericBackings.TryGetValue(interfaceType.GetGenericTypeDefinition(), out openBacking);
141141
}
142142
}
143143

src/Autofac.Extras.AggregateService/Polyfills.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
namespace System.Diagnostics.CodeAnalysis;
2020

2121
#if !NETSTANDARD2_1_OR_GREATER
22+
[ExcludeFromCodeCoverage]
2223
[AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
2324
internal sealed class NotNullWhenAttribute : Attribute
2425
{
@@ -34,6 +35,7 @@ public bool ReturnValue
3435
}
3536
#endif
3637

38+
[ExcludeFromCodeCoverage]
3739
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Constructor | AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
3840
internal sealed class RequiresUnreferencedCodeAttribute : Attribute
3941
{
@@ -53,6 +55,7 @@ public string? Url
5355
}
5456
}
5557

58+
[ExcludeFromCodeCoverage]
5659
[AttributeUsage(AttributeTargets.All, Inherited = false, AllowMultiple = true)]
5760
internal sealed class UnconditionalSuppressMessageAttribute : Attribute
5861
{
@@ -93,6 +96,7 @@ public string? Justification
9396
}
9497
}
9598

99+
[ExcludeFromCodeCoverage]
96100
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Constructor | AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
97101
internal sealed class RequiresDynamicCodeAttribute : Attribute
98102
{

src/Autofac.Extras.AggregateService/ResolvingInterceptor.cs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ public void Intercept(IInvocation invocation)
6161
}
6262

6363
return method
64-
.DeclaringType?
64+
.DeclaringType!
6565
.GetProperties()
6666
.FirstOrDefault(prop => prop.GetGetMethod() == method);
6767
}
@@ -155,8 +155,7 @@ private Dictionary<MethodInfo, Action<IInvocation>> SetupInvocationMap(Type inte
155155
}
156156

157157
// Methods without parameters
158-
var methodWithoutParams = GetType().GetMethod(nameof(MethodWithoutParams), BindingFlags.Instance | BindingFlags.NonPublic)
159-
?? throw new InvalidOperationException($"Unable to locate the {nameof(MethodWithoutParams)} method via reflection.");
158+
var methodWithoutParams = GetType().GetMethod(nameof(MethodWithoutParams), BindingFlags.Instance | BindingFlags.NonPublic)!;
160159
var methodWithoutParamsDelegate = (Action<IInvocation>)methodWithoutParams.CreateDelegate(typeof(Action<IInvocation>), this);
161160
methodMap.Add(method, methodWithoutParamsDelegate);
162161
}

src/Autofac.Extras.AggregateService/TypeExtensions.cs

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,6 @@ public static IEnumerable<Type> GetUniqueInterfaces(this Type type)
2525
var types = new HashSet<Type>();
2626
foreach (var interfaceType in type.GetInterfaces())
2727
{
28-
if (types.Contains(interfaceType))
29-
{
30-
continue;
31-
}
32-
3328
types.Add(interfaceType);
3429
}
3530

test/Autofac.Extras.AggregateService.Test/AggregateServiceGeneratorTests.cs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,17 @@ public void CreateInstance_InterfaceType()
1717
Assert.IsAssignableFrom<IAggregateService>(instance);
1818
}
1919

20+
[Fact]
21+
public void CreateInstance_NestedInterfaceType()
22+
{
23+
using var container = CreateContainer();
24+
25+
var instance = AggregateServiceGenerator.CreateInstance(typeof(INestedAggregateService), container);
26+
27+
var aggregateService = Assert.IsAssignableFrom<INestedAggregateService>(instance);
28+
Assert.NotNull(aggregateService.MyService);
29+
}
30+
2031
[Fact]
2132
public void CreateInstance_NullComponentContext()
2233
{
@@ -51,4 +62,12 @@ private static IContainer CreateContainer()
5162
builder.RegisterInstance(Substitute.For<IMyService>());
5263
return builder.Build();
5364
}
65+
66+
public interface INestedAggregateService
67+
{
68+
IMyService MyService
69+
{
70+
get;
71+
}
72+
}
5473
}
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
// Copyright (c) Autofac Project. All rights reserved.
2+
// Licensed under the MIT License. See LICENSE in the project root for license information.
3+
4+
using NSubstitute;
5+
6+
namespace Autofac.Extras.AggregateService.Test;
7+
8+
public class GeneratedAggregateServiceRegistryTests
9+
{
10+
[Fact]
11+
public void Register_NullFactory()
12+
{
13+
Assert.Throws<ArgumentNullException>(() => GeneratedAggregateServiceRegistry.Register(typeof(IClosedAggregate), null!));
14+
}
15+
16+
[Fact]
17+
public void Register_NullInterfaceType()
18+
{
19+
Assert.Throws<ArgumentNullException>(() => GeneratedAggregateServiceRegistry.Register(null!, _ => new ClosedAggregate()));
20+
}
21+
22+
[Fact]
23+
public void RegisterOpenGeneric_NullBackingType()
24+
{
25+
Assert.Throws<ArgumentNullException>(() => GeneratedAggregateServiceRegistry.RegisterOpenGeneric(typeof(IOpenAggregate<>), null!));
26+
}
27+
28+
[Fact]
29+
public void RegisterOpenGeneric_NullInterfaceType()
30+
{
31+
Assert.Throws<ArgumentNullException>(() => GeneratedAggregateServiceRegistry.RegisterOpenGeneric(null!, typeof(OpenAggregate<>)));
32+
}
33+
34+
[Fact]
35+
public void TryCreate_ClosedFactoryRegistered()
36+
{
37+
var expected = new ClosedAggregate();
38+
var context = Substitute.For<IComponentContext>();
39+
GeneratedAggregateServiceRegistry.Register(typeof(IClosedAggregate), receivedContext =>
40+
{
41+
Assert.Same(context, receivedContext);
42+
return expected;
43+
});
44+
45+
var created = GeneratedAggregateServiceRegistry.TryCreate(typeof(IClosedAggregate), context, out var instance);
46+
47+
Assert.True(created);
48+
Assert.Same(expected, instance);
49+
}
50+
51+
[Fact]
52+
public void TryCreate_NoRegisteredFactory()
53+
{
54+
var context = Substitute.For<IComponentContext>();
55+
56+
var created = GeneratedAggregateServiceRegistry.TryCreate(typeof(IUnregisteredAggregate), context, out var instance);
57+
58+
Assert.False(created);
59+
Assert.Null(instance);
60+
}
61+
62+
[Fact]
63+
public void TryCreate_OpenGenericBackingRegistered()
64+
{
65+
var context = Substitute.For<IComponentContext>();
66+
GeneratedAggregateServiceRegistry.RegisterOpenGeneric(typeof(IOpenAggregate<>), typeof(OpenAggregate<>));
67+
68+
var created = GeneratedAggregateServiceRegistry.TryCreate(typeof(IOpenAggregate<string>), context, out var instance);
69+
70+
var aggregate = Assert.IsType<OpenAggregate<string>>(instance);
71+
Assert.True(created);
72+
Assert.Same(context, aggregate.Context);
73+
}
74+
75+
public interface IClosedAggregate
76+
{
77+
}
78+
79+
public interface IOpenAggregate<T>
80+
{
81+
}
82+
83+
public interface IUnregisteredAggregate
84+
{
85+
}
86+
87+
public sealed class ClosedAggregate : IClosedAggregate
88+
{
89+
}
90+
91+
public sealed class OpenAggregate<T> : IOpenAggregate<T>
92+
{
93+
public OpenAggregate(IComponentContext context)
94+
{
95+
Context = context;
96+
}
97+
98+
public IComponentContext Context
99+
{
100+
get;
101+
}
102+
}
103+
}

0 commit comments

Comments
 (0)