Skip to content

Commit 4abe129

Browse files
throw InvalidOperationException in case a required service or a fromkeyedservice constructor argument can't be resolved. Also a change for GetRequiredService as behaviour was not the same and compliance tests were not testing this good
1 parent fd04c75 commit 4abe129

File tree

5 files changed

+51
-11
lines changed

5 files changed

+51
-11
lines changed

src/Ninject.Web.AspNetCore.Test/Unit/DuplicateDescriptorTest.cs

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,15 @@ public void BindingsFromKernel_ResolveWarrior_FailsWithActivationException(Resol
6666
else
6767
{
6868
Action action = () => resolver.Resolve<IWarrior>(kernel);
69-
action.Should().Throw<ActivationException>().WithMessage("Error activating IWarrior*");
69+
if (resolver.ResolveType == ResolveType.ServiceProviderRequired)
70+
{
71+
action.Should().Throw<InvalidOperationException>().WithInnerException<ActivationException>()
72+
.WithMessage("Error activating IWarrior*");
73+
}
74+
else
75+
{
76+
action.Should().Throw<ActivationException>().WithMessage("Error activating IWarrior*");
77+
}
7078
}
7179
}
7280

@@ -99,7 +107,15 @@ public void BindingsMixedWarriorDescriptors_ResolveWarrior_FailsWithActivationEx
99107
else
100108
{
101109
Action action = () => resolver.Resolve<IWarrior>(kernel);
102-
action.Should().Throw<ActivationException>().WithMessage("Error activating IWeapon*");
110+
if (resolver.ResolveType == ResolveType.ServiceProviderRequired)
111+
{
112+
action.Should().Throw<InvalidOperationException>().WithInnerException<ActivationException>()
113+
.WithMessage("Error activating IWeapon*");
114+
}
115+
else
116+
{
117+
action.Should().Throw<ActivationException>().WithMessage("Error activating IWeapon*");
118+
}
103119
}
104120
}
105121

src/Ninject.Web.AspNetCore.Test/Unit/ServiceProviderKeyedTest.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ public void RequiredKeyedNonExisting_SingleServiceResolvedToException()
172172
var provider = CreateServiceProvider(kernel);
173173

174174
Action action = () => provider.GetRequiredKeyedService(typeof(IWarrior), "Samurai");
175-
action.Should().Throw<ActivationException>().WithMessage("*No matching bindings are available*");
175+
action.Should().Throw<InvalidOperationException>().WithInnerException<ActivationException>().WithMessage("*No matching bindings are available*");
176176
}
177177

178178
[Fact]
@@ -216,7 +216,7 @@ public void ExistingMultipleServices_ResolvesNonKeyedToException()
216216
var provider = CreateServiceProvider(kernel);
217217

218218
Action action = () => provider.GetRequiredService(typeof(IWarrior));
219-
action.Should().Throw<ActivationException>().WithMessage("*No matching bindings are available, and the type is not self-bindable.*");
219+
action.Should().Throw<InvalidOperationException>().WithInnerException<ActivationException>().WithMessage("*No matching bindings are available, and the type is not self-bindable.*");
220220
}
221221

222222
private IServiceProvider CreateServiceProvider(AspNetCoreKernel kernel)

src/Ninject.Web.AspNetCore.Test/Unit/ServiceProviderTest.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ public void RequiredNonExistingSingleServiceResolvedToException()
8686
var provider = CreateServiceProvider(kernel);
8787

8888
Action action = () => provider.GetRequiredService(typeof(IWarrior));
89-
action.Should().Throw<ActivationException>().WithMessage("*No matching bindings are available*");
89+
action.Should().Throw<InvalidOperationException>().WithInnerException<ActivationException>().WithMessage("*No matching bindings are available*");
9090
}
9191

9292
[Fact]
@@ -115,7 +115,7 @@ public void RequiredExistingMultipleServicesResolvedToExceptionWhenNotQueriedAsL
115115
var provider = CreateServiceProvider(kernel);
116116

117117
Action action = () => provider.GetRequiredService(typeof(IWarrior));
118-
action.Should().Throw<ActivationException>().WithMessage("*More than one matching bindings are available*");
118+
action.Should().Throw<InvalidOperationException>().WithInnerException<ActivationException>().WithMessage("*More than one matching bindings are available*");
119119
}
120120

121121
[Fact]

src/Ninject.Web.AspNetCore/NinjectServiceProvider.cs

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,14 @@ public object GetRequiredService(Type serviceType)
4646
{
4747
if (!IsListType(serviceType, out var elementType))
4848
{
49-
return _resolutionRoot.Get(serviceType, metadata => !metadata.HasServiceKeyMetadata());
49+
try
50+
{
51+
return _resolutionRoot.Get(serviceType, metadata => !metadata.HasServiceKeyMetadata());
52+
}
53+
catch (ActivationException ex)
54+
{
55+
throw new InvalidOperationException($"Can't resolve service of Type {serviceType}", ex);
56+
}
5057
}
5158
else
5259
{
@@ -117,7 +124,14 @@ public object GetRequiredKeyedService(Type serviceType, object serviceKey)
117124
if (!IsListType(serviceType, out var elementType))
118125
{
119126
EnsureNotAnyKey(serviceKey, serviceType);
120-
return ResolveKeyedService<object>(serviceType, serviceKey, true, false);
127+
try
128+
{
129+
return ResolveKeyedService<object>(serviceType, serviceKey, true, false);
130+
}
131+
catch (ActivationException ex)
132+
{
133+
throw new InvalidOperationException($"Can't resolve service of Type {serviceType} with service key {serviceKey}", ex);
134+
}
121135
}
122136
else
123137
{

src/Ninject.Web.AspNetCore/Planning/ParameterTargetWithKeyedSupport.cs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,10 +63,20 @@ private object ResolveFromKeyedService(IContext parent, FromKeyedServicesAttribu
6363
var fromKeyedServiceValue = DeterimeFromKeyedServiceValue(keyedattribute, parent.Parameters);
6464
var additionalConstraint = fromKeyedServiceValue != null
6565
? metadata => metadata.DoesMetadataMatchServiceKey(fromKeyedServiceValue)
66-
: (Func<IBindingMetadata, bool>) null;
67-
var child = parent.Request.CreateKeyedChildRequest(Type, fromKeyedServiceValue, parent, this, additionalConstraint);
66+
: (Func<IBindingMetadata, bool>)null;
67+
var child = parent.Request.CreateKeyedChildRequest(Type, fromKeyedServiceValue, parent, this,
68+
additionalConstraint);
6869
child.IsUnique = true;
69-
return parent.Kernel.Resolve(child).SingleOrDefault();
70+
child.IsOptional = false; // constructor arguments marked with FromKeyedServices must always resolve, otherwise an InvalidOperationException is expected.
71+
try
72+
{
73+
return parent.Kernel.Resolve(child).SingleOrDefault();
74+
}
75+
catch (ActivationException ex)
76+
{
77+
throw new InvalidOperationException(
78+
$"Can't resolve keyed service of Type {Type} with key {fromKeyedServiceValue}", ex);
79+
}
7080
}
7181

7282
private object DeterimeFromKeyedServiceValue(

0 commit comments

Comments
 (0)