Skip to content

Commit f680ece

Browse files
Refactor to use a default internal container and dependency resolver instead of static singletons
1 parent e29d885 commit f680ece

19 files changed

+160
-78
lines changed

src/AspNet/OData/test/Asp.Versioning.WebApi.OData.Tests/Controllers/VersionedMetadataControllerTest.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ public async Task options_should_return_expected_headers()
3737
configuration.AddApiVersioning(
3838
options =>
3939
{
40+
options.ReportApiVersions = true;
4041
options.Policies.Sunset( "VersionedMetadata" )
4142
.Link( "policies" )
4243
.Title( "Versioning Policy" )

src/AspNet/WebApi/src/Asp.Versioning.WebApi.ApiExplorer/ApiExplorer/VersionedApiExplorer.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ public IDocumentationProvider DocumentationProvider
101101
/// <value>The configured <see cref="ISunsetPolicyManager">sunset policy manager</see>.</value>
102102
protected ISunsetPolicyManager SunsetPolicyManager
103103
{
104-
get => sunsetPolicyManager ??= Configuration.DependencyResolver.GetSunsetPolicyManager();
104+
get => sunsetPolicyManager ??= Configuration.GetSunsetPolicyManager();
105105
set => sunsetPolicyManager = value;
106106
}
107107

@@ -227,7 +227,7 @@ protected virtual ApiDescriptionGroupCollection InitializeApiDescriptions()
227227
}
228228

229229
var routes = FlattenRoutes( Configuration.Routes ).ToArray();
230-
var policyManager = Configuration.DependencyResolver.GetSunsetPolicyManager();
230+
var policyManager = Configuration.GetSunsetPolicyManager();
231231

232232
foreach ( var apiVersion in FlattenApiVersions( controllerMappings ) )
233233
{

src/AspNet/WebApi/src/Asp.Versioning.WebApi/ApiVersionRequestProperties.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ public ApiVersion? RequestedApiVersion
8888
return apiVersion;
8989
}
9090

91-
var parser = request.GetConfiguration().DependencyResolver.GetApiVersionParser();
91+
var parser = request.GetConfiguration().GetApiVersionParser();
9292

9393
try
9494
{

src/AspNet/WebApi/src/Asp.Versioning.WebApi/DefaultApiVersionReporter.cs

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,6 @@ namespace Asp.Versioning;
1010
/// </content>
1111
public partial class DefaultApiVersionReporter
1212
{
13-
private static DefaultApiVersionReporter? instance;
14-
15-
internal static IReportApiVersions GetOrCreate( ISunsetPolicyManager sunsetPolicyManager ) =>
16-
instance ??= new( sunsetPolicyManager );
17-
1813
private static void AddApiVersionHeader( HttpResponseHeaders headers, string headerName, IReadOnlyList<ApiVersion> versions )
1914
{
2015
if ( versions.Count == 0 || headers.Contains( headerName ) )
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
// Copyright (c) .NET Foundation and contributors. All rights reserved.
2+
3+
namespace Asp.Versioning.Dependencies;
4+
5+
using Asp.Versioning;
6+
using Asp.Versioning.Conventions;
7+
using System.ComponentModel.Design;
8+
using System.Web.Http.Dependencies;
9+
10+
internal sealed class DefaultContainer : IDependencyResolver, IDependencyScope
11+
{
12+
private readonly ServiceContainer container = new();
13+
private bool disposed;
14+
15+
internal DefaultContainer()
16+
{
17+
container.AddService( typeof( ApiVersioningOptions ), static ( sc, t ) => new ApiVersioningOptions() );
18+
container.AddService( typeof( IApiVersionParser ), static ( sc, t ) => ApiVersionParser.Default );
19+
container.AddService( typeof( IControllerNameConvention ), static ( sc, t ) => ControllerNameConvention.Default );
20+
container.AddService( typeof( IProblemDetailsFactory ), static ( sc, t ) => new ProblemDetailsFactory() );
21+
container.AddService( typeof( ISunsetPolicyManager ), NewSunsetPolicyManager );
22+
container.AddService( typeof( IReportApiVersions ), NewApiVersionReporter );
23+
}
24+
25+
public ApiVersioningOptions ApiVersioningOptions
26+
{
27+
get => GetApiVersioningOptions( container );
28+
set
29+
{
30+
container.RemoveService( typeof( ApiVersioningOptions ) );
31+
container.AddService( typeof( ApiVersioningOptions ), value );
32+
}
33+
}
34+
35+
public void Replace( Type serviceType, ServiceCreatorCallback activator )
36+
{
37+
container.RemoveService( serviceType );
38+
container.AddService( serviceType, activator );
39+
}
40+
41+
public IDependencyScope BeginScope() => this;
42+
43+
public void Dispose()
44+
{
45+
if ( disposed )
46+
{
47+
return;
48+
}
49+
50+
disposed = true;
51+
container.Dispose();
52+
}
53+
54+
public object GetService( Type serviceType ) => container.GetService( serviceType );
55+
56+
public IEnumerable<object> GetServices( Type serviceType )
57+
{
58+
var service = container.GetService( serviceType );
59+
60+
if ( service is not null )
61+
{
62+
yield return service;
63+
}
64+
}
65+
66+
private static ApiVersioningOptions GetApiVersioningOptions( IServiceProvider serviceProvider ) =>
67+
(ApiVersioningOptions) serviceProvider.GetService( typeof( ApiVersioningOptions ) );
68+
69+
private static ISunsetPolicyManager NewSunsetPolicyManager( IServiceProvider serviceProvider, Type type ) =>
70+
new SunsetPolicyManager( GetApiVersioningOptions( serviceProvider ) );
71+
72+
private static IReportApiVersions NewApiVersionReporter( IServiceProvider serviceProvider, Type type )
73+
{
74+
var options = GetApiVersioningOptions( serviceProvider );
75+
76+
if ( options.ReportApiVersions )
77+
{
78+
var sunsetPolicyManager = (ISunsetPolicyManager) serviceProvider.GetService( typeof( ISunsetPolicyManager ) );
79+
return new DefaultApiVersionReporter( sunsetPolicyManager );
80+
}
81+
82+
return new DoNotReportApiVersions();
83+
}
84+
}

src/AspNet/WebApi/src/Asp.Versioning.WebApi/DependencyResolverExtensions.cs

Lines changed: 31 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,24 +3,39 @@
33
namespace Asp.Versioning;
44

55
using Asp.Versioning.Conventions;
6+
using System.Globalization;
7+
using System.Web.Http;
68
using System.Web.Http.Dependencies;
79

810
internal static class DependencyResolverExtensions
911
{
10-
internal static TService? GetService<TService>( this IDependencyResolver resolver ) => (TService) resolver.GetService( typeof( TService ) );
11-
12-
internal static IApiVersionParser GetApiVersionParser( this IDependencyResolver resolver ) =>
13-
resolver.GetService<IApiVersionParser>() ?? ApiVersionParser.Default;
14-
15-
internal static IReportApiVersions GetApiVersionReporter( this IDependencyResolver resolver ) =>
16-
resolver.GetService<IReportApiVersions>() ?? DefaultApiVersionReporter.GetOrCreate( resolver.GetSunsetPolicyManager() );
17-
18-
internal static IControllerNameConvention GetControllerNameConvention( this IDependencyResolver resolver ) =>
19-
resolver.GetService<IControllerNameConvention>() ?? ControllerNameConvention.Default;
20-
21-
internal static IProblemDetailsFactory GetProblemDetailsFactory( this IDependencyResolver resolver ) =>
22-
resolver.GetService<IProblemDetailsFactory>() ?? ProblemDetailsFactory.Default;
23-
24-
internal static ISunsetPolicyManager GetSunsetPolicyManager( this IDependencyResolver resolver ) =>
25-
resolver.GetService<ISunsetPolicyManager>() ?? SunsetPolicyManager.Default;
12+
internal static TService? GetService<TService>( this IDependencyResolver resolver ) =>
13+
(TService) resolver.GetService( typeof( TService ) );
14+
15+
internal static TService GetRequiredService<TService>( this IDependencyResolver resolver )
16+
{
17+
var service = resolver.GetService<TService>();
18+
var message = string.Format( CultureInfo.CurrentCulture, SR.NoServiceRegistered, typeof( TService ) );
19+
return service ?? throw new InvalidOperationException( message );
20+
}
21+
22+
internal static IApiVersionParser GetApiVersionParser( this HttpConfiguration configuration ) =>
23+
configuration.DependencyResolver.GetService<IApiVersionParser>() ??
24+
configuration.ApiVersioningServices().GetRequiredService<IApiVersionParser>();
25+
26+
internal static IReportApiVersions GetApiVersionReporter( this HttpConfiguration configuration ) =>
27+
configuration.DependencyResolver.GetService<IReportApiVersions>() ??
28+
configuration.ApiVersioningServices().GetRequiredService<IReportApiVersions>();
29+
30+
internal static IControllerNameConvention GetControllerNameConvention( this HttpConfiguration configuration ) =>
31+
configuration.DependencyResolver.GetService<IControllerNameConvention>() ??
32+
configuration.ApiVersioningServices().GetRequiredService<IControllerNameConvention>();
33+
34+
internal static IProblemDetailsFactory GetProblemDetailsFactory( this HttpConfiguration configuration ) =>
35+
configuration.DependencyResolver.GetService<IProblemDetailsFactory>() ??
36+
configuration.ApiVersioningServices().GetRequiredService<IProblemDetailsFactory>();
37+
38+
internal static ISunsetPolicyManager GetSunsetPolicyManager( this HttpConfiguration configuration ) =>
39+
configuration.DependencyResolver.GetService<ISunsetPolicyManager>() ??
40+
configuration.ApiVersioningServices().GetRequiredService<ISunsetPolicyManager>();
2641
}

src/AspNet/WebApi/src/Asp.Versioning.WebApi/Dispatcher/ApiVersionControllerSelector.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,7 @@ private static void ApplyImplicitConventions( HttpControllerDescriptor controlle
221221
}
222222

223223
var actions = mapping.SelectMany( g => g );
224-
var namingConvention = controller.Configuration.DependencyResolver.GetControllerNameConvention();
224+
var namingConvention = controller.Configuration.GetControllerNameConvention();
225225
var name = namingConvention.GroupName( controller.ControllerName );
226226
var metadata = new ApiVersionMetadata( implicitVersionModel, implicitVersionModel, name );
227227

@@ -344,7 +344,7 @@ private static void ApplyCollatedModelsToActions(
344344
HttpConfiguration configuration,
345345
List<Tuple<HttpControllerDescriptor, HttpActionDescriptor, ApiVersionModel>> visitedActions )
346346
{
347-
var namingConvention = configuration.DependencyResolver.GetControllerNameConvention();
347+
var namingConvention = configuration.GetControllerNameConvention();
348348

349349
for ( var i = 0; i < visitedActions.Count; i++ )
350350
{

src/AspNet/WebApi/src/Asp.Versioning.WebApi/Dispatcher/HttpControllerTypeCache.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ private Dictionary<string, ILookup<string, Type>> InitializeCache()
3333
var services = configuration.Services;
3434
var assembliesResolver = services.GetAssembliesResolver();
3535
var typeResolver = services.GetHttpControllerTypeResolver();
36-
var convention = configuration.DependencyResolver.GetControllerNameConvention();
36+
var convention = configuration.GetControllerNameConvention();
3737
var comparer = StringComparer.OrdinalIgnoreCase;
3838

3939
return typeResolver.GetControllerTypes( assembliesResolver )

src/AspNet/WebApi/src/Asp.Versioning.WebApi/Dispatcher/HttpResponseExceptionFactory.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ internal HttpResponseExceptionFactory( HttpRequestMessage request, ApiVersionMod
3636

3737
private ApiVersioningOptions Options => configuration.GetApiVersioningOptions();
3838

39-
private IProblemDetailsFactory ProblemDetails => configuration.DependencyResolver.GetProblemDetailsFactory();
39+
private IProblemDetailsFactory ProblemDetails => configuration.GetProblemDetailsFactory();
4040

4141
private ITraceWriter TraceWriter => configuration.Services.GetTraceWriter() ?? NullTraceWriter.Instance;
4242

src/AspNet/WebApi/src/Asp.Versioning.WebApi/DoNotReportApiVersions.cs

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,6 @@ namespace Asp.Versioning;
66

77
internal sealed class DoNotReportApiVersions : IReportApiVersions
88
{
9-
private static DoNotReportApiVersions? instance;
10-
11-
private DoNotReportApiVersions() { }
12-
13-
internal static IReportApiVersions Instance => instance ??= new();
14-
159
public ApiVersionMapping Mapping => Explicit | Implicit;
1610

1711
public void Report( HttpResponseMessage response, ApiVersionModel apiVersionModel ) { }

0 commit comments

Comments
 (0)