Skip to content
This repository was archived by the owner on Nov 2, 2018. It is now read-only.

Commit 3e3724c

Browse files
committed
Another test and exception message
1 parent 9d352ad commit 3e3724c

File tree

5 files changed

+48
-7
lines changed

5 files changed

+48
-7
lines changed

src/Microsoft.Extensions.DependencyInjection/Properties/Resources.Designer.cs

Lines changed: 16 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Microsoft.Extensions.DependencyInjection/Resources.resx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,4 +147,7 @@
147147
<data name="ScopedResolvedFromRootException" xml:space="preserve">
148148
<value>Cannot resolve '{0}' from root provider because it requires {2} service '{1}'.</value>
149149
</data>
150+
<data name="DirectScopedResolvedFromRootException" xml:space="preserve">
151+
<value>Cannot resolve {1} service '{0}' from root provider.</value>
152+
</data>
150153
</root>

src/Microsoft.Extensions.DependencyInjection/ServiceCollectionContainerBuilderExtensions.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ public static class ServiceCollectionContainerBuilderExtensions
1111
/// Creates an <see cref="IServiceProvider"/> containing services from the provided <see cref="IServiceCollection"/>.
1212
/// </summary>
1313
/// <param name="services">The <see cref="IServiceCollection"/> containing service descriptors.</param>
14-
/// <returns>An instance of <see cref="IServiceProvider"/> providing access to services.</returns>
14+
/// <returns>The<see cref="IServiceProvider"/>.</returns>
15+
1516
public static IServiceProvider BuildServiceProvider(this IServiceCollection services)
1617
{
1718
return BuildServiceProvider(services, validateScopes: false);
@@ -25,7 +26,7 @@ public static IServiceProvider BuildServiceProvider(this IServiceCollection serv
2526
/// <param name="validateScopes">
2627
/// <c>true</c> to perform check verifying that scoped services never gets resolved from root provider; otherwise <c>false</c>.
2728
/// </param>
28-
/// <returns>An instance of <see cref="IServiceProvider"/> providing access to services.</returns>
29+
/// <returns>The<see cref="IServiceProvider"/>.</returns>
2930
public static IServiceProvider BuildServiceProvider(this IServiceCollection services, bool validateScopes)
3031
{
3132
return new ServiceProvider(services, validateScopes);

src/Microsoft.Extensions.DependencyInjection/ServiceLookup/CallSiteValidator.cs

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ namespace Microsoft.Extensions.DependencyInjection.ServiceLookup
88
{
99
internal class CallSiteValidator: CallSiteVisitor<CallSiteValidator.CallSiteValidatorState, Type>
1010
{
11+
// Keys are services being resolved via GetService, values - first scoped service in their call site tree
1112
private readonly Dictionary<Type, Type> _scopedServices = new Dictionary<Type, Type>();
1213

1314
public void ValidateCallSite(Type serviceType, IServiceCallSite callSite)
@@ -25,10 +26,18 @@ public void ValidateResolution(Type serviceType, ServiceProvider serviceProvider
2526
if (ReferenceEquals(serviceProvider, serviceProvider.Root)
2627
&& _scopedServices.TryGetValue(serviceType, out scopedService))
2728
{
28-
throw new InvalidOperationException(Resources.FormatScopedResolvedFromRootException(
29-
serviceType,
30-
scopedService,
31-
nameof(ServiceLifetime.Scoped).ToLowerInvariant()));
29+
if (serviceType == scopedService)
30+
{
31+
throw new InvalidOperationException(
32+
Resources.FormatDirectScopedResolvedFromRootException(serviceType,
33+
nameof(ServiceLifetime.Scoped).ToLowerInvariant()));
34+
}
35+
36+
throw new InvalidOperationException(
37+
Resources.FormatScopedResolvedFromRootException(
38+
serviceType,
39+
scopedService,
40+
nameof(ServiceLifetime.Scoped).ToLowerInvariant()));
3241
}
3342
}
3443

test/Microsoft.Extensions.DependencyInjection.Tests/ServiceProviderValidationTests.cs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,19 @@ public void GetService_Throws_WhenScopedIsInjectedIntoSingletonThroughSingleton(
5454

5555
[Fact]
5656
public void GetService_Throws_WhenGetServiceForScopedServiceIsCalledOnRoot()
57+
{
58+
// Arrange
59+
var serviceCollection = new ServiceCollection();
60+
serviceCollection.AddScoped<IBar, Bar>();
61+
var serviceProvider = serviceCollection.BuildServiceProvider(validateScopes: true);
62+
63+
// Act + Assert
64+
var exception = Assert.Throws<InvalidOperationException>(() => serviceProvider.GetService(typeof(IBar)));
65+
Assert.Equal($"Cannot resolve scoped service '{typeof(IBar)}' from root provider.", exception.Message);
66+
}
67+
68+
[Fact]
69+
public void GetService_Throws_WhenGetServiceForScopedServiceIsCalledOnRootViaTransient()
5770
{
5871
// Arrange
5972
var serviceCollection = new ServiceCollection();
@@ -67,7 +80,6 @@ public void GetService_Throws_WhenGetServiceForScopedServiceIsCalledOnRoot()
6780
}
6881

6982
[Fact]
70-
7183
public void GetService_DoesNotThrow_WhenScopeFactoryIsInjectedIntoSingleton()
7284
{
7385
// Arrange

0 commit comments

Comments
 (0)