Skip to content

Commit

Permalink
use file scoped namespaces in Handyman.AspNetCore
Browse files Browse the repository at this point in the history
  • Loading branch information
JonasSamuelsson committed Sep 2, 2024
1 parent d4ecc7c commit bace320
Show file tree
Hide file tree
Showing 45 changed files with 903 additions and 944 deletions.
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
namespace Handyman.AspNetCore.ApiVersioning.Abstractions
namespace Handyman.AspNetCore.ApiVersioning.Abstractions;

internal class ApiVersionDescriptor
{
internal class ApiVersionDescriptor
{
public IApiVersion[] Versions { get; set; }
public bool IsOptional { get; set; }
public IApiVersion DefaultVersion { get; set; }
}
public IApiVersion[] Versions { get; set; }
public bool IsOptional { get; set; }
public IApiVersion DefaultVersion { get; set; }
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,73 +2,72 @@
using System;
using System.Linq;

namespace Handyman.AspNetCore.ApiVersioning.Abstractions
namespace Handyman.AspNetCore.ApiVersioning.Abstractions;

internal class ApiVersionDescriptorProvider : IActionDescriptorProvider
{
internal class ApiVersionDescriptorProvider : IActionDescriptorProvider
{
private readonly IApiVersionParser _apiVersionParser;
private readonly IApiVersionParser _apiVersionParser;

public ApiVersionDescriptorProvider(IApiVersionParser apiVersionParser)
{
_apiVersionParser = apiVersionParser;
}
public ApiVersionDescriptorProvider(IApiVersionParser apiVersionParser)
{
_apiVersionParser = apiVersionParser;
}

public int Order { get; } = 0;
public int Order { get; } = 0;

public void OnProvidersExecuting(ActionDescriptorProviderContext context)
public void OnProvidersExecuting(ActionDescriptorProviderContext context)
{
foreach (var action in context.Results)
{
foreach (var action in context.Results)
{
var filterDescriptor = action.FilterDescriptors.SingleOrDefault(x => x.Filter is ApiVersionAttribute);
var filterDescriptor = action.FilterDescriptors.SingleOrDefault(x => x.Filter is ApiVersionAttribute);

if (filterDescriptor == null)
continue;
if (filterDescriptor == null)
continue;

var attribute = (ApiVersionAttribute)filterDescriptor.Filter;
var apiVersionDescriptor = GetApiVersionDescriptor(action, attribute);
action.EndpointMetadata.Add(apiVersionDescriptor);
}
var attribute = (ApiVersionAttribute)filterDescriptor.Filter;
var apiVersionDescriptor = GetApiVersionDescriptor(action, attribute);
action.EndpointMetadata.Add(apiVersionDescriptor);
}
}

private ApiVersionDescriptor GetApiVersionDescriptor(ActionDescriptor action, ApiVersionAttribute apiVersionAttribute)
{
if (apiVersionAttribute.Versions.Count == 0)
throw new InvalidOperationException($"{action.DisplayName} : does not have any supported versions.");
private ApiVersionDescriptor GetApiVersionDescriptor(ActionDescriptor action, ApiVersionAttribute apiVersionAttribute)
{
if (apiVersionAttribute.Versions.Count == 0)
throw new InvalidOperationException($"{action.DisplayName} : does not have any supported versions.");

var defaultApiVersion = !string.IsNullOrWhiteSpace(apiVersionAttribute.DefaultVersion)
? ParseApiVersion(apiVersionAttribute.DefaultVersion, action)
: null;
var defaultApiVersion = !string.IsNullOrWhiteSpace(apiVersionAttribute.DefaultVersion)
? ParseApiVersion(apiVersionAttribute.DefaultVersion, action)
: null;

var apiVersions = apiVersionAttribute.Versions
.Select(x => ParseApiVersion(x, action))
.ToArray();
var apiVersions = apiVersionAttribute.Versions
.Select(x => ParseApiVersion(x, action))
.ToArray();

if (defaultApiVersion != null)
if (defaultApiVersion != null)
{
if (apiVersions.All(x => x.Text != defaultApiVersion.Text))
{
if (apiVersions.All(x => x.Text != defaultApiVersion.Text))
{
throw new InvalidOperationException($"{action.DisplayName} : default version does not match any of the supported versions.");
}
throw new InvalidOperationException($"{action.DisplayName} : default version does not match any of the supported versions.");
}

return new ApiVersionDescriptor
{
DefaultVersion = defaultApiVersion,
IsOptional = apiVersionAttribute.Optional,
Versions = apiVersions
};
}

private IApiVersion ParseApiVersion(string version, ActionDescriptor action)
return new ApiVersionDescriptor
{
if (_apiVersionParser.TryParse(version, out var apiVersion))
return apiVersion;
DefaultVersion = defaultApiVersion,
IsOptional = apiVersionAttribute.Optional,
Versions = apiVersions
};
}

throw new FormatException($"{action.DisplayName} : version '{version}' has an invalid format.");
}
private IApiVersion ParseApiVersion(string version, ActionDescriptor action)
{
if (_apiVersionParser.TryParse(version, out var apiVersion))
return apiVersion;

public void OnProvidersExecuted(ActionDescriptorProviderContext context)
{
}
throw new FormatException($"{action.DisplayName} : version '{version}' has an invalid format.");
}

public void OnProvidersExecuted(ActionDescriptorProviderContext context)
{
}
}
45 changes: 22 additions & 23 deletions src/Handyman.AspNetCore/src/ApiVersioning/ApiVersionAttribute.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,32 +2,31 @@
using Microsoft.Extensions.Primitives;
using System;

namespace Handyman.AspNetCore.ApiVersioning
namespace Handyman.AspNetCore.ApiVersioning;

// ReSharper disable once RedundantAttributeUsageProperty
[AttributeUsage(AttributeTargets.Method, Inherited = false, AllowMultiple = false)]
public sealed class ApiVersionAttribute : Attribute, IFilterMetadata
{
// ReSharper disable once RedundantAttributeUsageProperty
[AttributeUsage(AttributeTargets.Method, Inherited = false, AllowMultiple = false)]
public sealed class ApiVersionAttribute : Attribute, IFilterMetadata
public ApiVersionAttribute(string version)
: this(new[] { version })
{
public ApiVersionAttribute(string version)
: this(new[] { version })
{
}
}

public ApiVersionAttribute(string[] versions)
{
Versions = versions;
}
public ApiVersionAttribute(string[] versions)
{
Versions = versions;
}

/// <summary>
/// Specify the default version to use if api version is optional and not provided in the request.
/// </summary>
public string DefaultVersion { get; set; }
/// <summary>
/// Specify the default version to use if api version is optional and not provided in the request.
/// </summary>
public string DefaultVersion { get; set; }

/// <summary>
/// Specify if an api version is optional or not, default is false.
/// </summary>
public bool Optional { get; set; }
/// <summary>
/// Specify if an api version is optional or not, default is false.
/// </summary>
public bool Optional { get; set; }

internal StringValues Versions { get; }
}
}
internal StringValues Versions { get; }
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
namespace Handyman.AspNetCore.ApiVersioning
namespace Handyman.AspNetCore.ApiVersioning;

internal class ApiVersionFeature
{
internal class ApiVersionFeature
{
internal string MatchedVersion { get; set; }
}
internal string MatchedVersion { get; set; }
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
namespace Handyman.AspNetCore.ApiVersioning
namespace Handyman.AspNetCore.ApiVersioning;

public class ApiVersionOptions
{
public class ApiVersionOptions
{
public int InvalidApiVersionStatusCode { get; set; }
}
public int InvalidApiVersionStatusCode { get; set; }
}
11 changes: 5 additions & 6 deletions src/Handyman.AspNetCore/src/ApiVersioning/IApiVersion.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
namespace Handyman.AspNetCore.ApiVersioning
namespace Handyman.AspNetCore.ApiVersioning;

public interface IApiVersion
{
public interface IApiVersion
{
string Text { get; }
string Text { get; }

bool IsMatch(IApiVersion other);
}
bool IsMatch(IApiVersion other);
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
namespace Handyman.AspNetCore.ApiVersioning
namespace Handyman.AspNetCore.ApiVersioning;

public interface IApiVersionParser
{
public interface IApiVersionParser
{
bool TryParse(string candidate, out IApiVersion version);
}
bool TryParse(string candidate, out IApiVersion version);
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Primitives;

namespace Handyman.AspNetCore.ApiVersioning
namespace Handyman.AspNetCore.ApiVersioning;

public interface IApiVersionReader
{
public interface IApiVersionReader
{
bool TryRead(HttpRequest httpRequest, out StringValues values);
}
bool TryRead(HttpRequest httpRequest, out StringValues values);
}
Original file line number Diff line number Diff line change
@@ -1,21 +1,20 @@
using System;
using System.Diagnostics;

namespace Handyman.AspNetCore.ApiVersioning.MajorMinorPreReleaseVersionScheme
namespace Handyman.AspNetCore.ApiVersioning.MajorMinorPreReleaseVersionScheme;

[DebuggerDisplay("major/minor/pre-release: {Text}")]
internal class MajorMinorPreReleaseApiVersion : IApiVersion
{
[DebuggerDisplay("major/minor/pre-release: {Text}")]
internal class MajorMinorPreReleaseApiVersion : IApiVersion
{
public string Text { get; }
public string Text { get; }

internal MajorMinorPreReleaseApiVersion(string version)
{
Text = version;
}
internal MajorMinorPreReleaseApiVersion(string version)
{
Text = version;
}

public bool IsMatch(IApiVersion other)
{
return other is MajorMinorPreReleaseApiVersion o && Text.Equals(o.Text, StringComparison.OrdinalIgnoreCase);
}
public bool IsMatch(IApiVersion other)
{
return other is MajorMinorPreReleaseApiVersion o && Text.Equals(o.Text, StringComparison.OrdinalIgnoreCase);
}
}
Original file line number Diff line number Diff line change
@@ -1,21 +1,20 @@
using System.Text.RegularExpressions;

namespace Handyman.AspNetCore.ApiVersioning.MajorMinorPreReleaseVersionScheme
namespace Handyman.AspNetCore.ApiVersioning.MajorMinorPreReleaseVersionScheme;

internal class MajorMinorPreReleaseApiVersionParser : IApiVersionParser
{
internal class MajorMinorPreReleaseApiVersionParser : IApiVersionParser
{
private static readonly Regex Regex = new Regex(@"^\d+(\.\d+)?(-[.0-9a-z]+)?$", RegexOptions.Compiled | RegexOptions.IgnoreCase);
private static readonly Regex Regex = new Regex(@"^\d+(\.\d+)?(-[.0-9a-z]+)?$", RegexOptions.Compiled | RegexOptions.IgnoreCase);

public bool TryParse(string candidate, out IApiVersion version)
public bool TryParse(string candidate, out IApiVersion version)
{
if (string.IsNullOrWhiteSpace(candidate) || !Regex.IsMatch(candidate))
{
if (string.IsNullOrWhiteSpace(candidate) || !Regex.IsMatch(candidate))
{
version = null;
return false;
}

version = new MajorMinorPreReleaseApiVersion(candidate);
return true;
version = null;
return false;
}

version = new MajorMinorPreReleaseApiVersion(candidate);
return true;
}
}
Original file line number Diff line number Diff line change
@@ -1,20 +1,19 @@
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using System.Threading.Tasks;

namespace Handyman.AspNetCore.ApiVersioning.ModelBinding
namespace Handyman.AspNetCore.ApiVersioning.ModelBinding;

internal class ApiVersionModelBinder : IModelBinder
{
internal class ApiVersionModelBinder : IModelBinder
public Task BindModelAsync(ModelBindingContext bindingContext)
{
public Task BindModelAsync(ModelBindingContext bindingContext)
{
var feature = bindingContext.HttpContext.Features.Get<ApiVersionFeature>();

if (feature != null)
{
bindingContext.Result = ModelBindingResult.Success(feature.MatchedVersion);
}
var feature = bindingContext.HttpContext.Features.Get<ApiVersionFeature>();

return Task.CompletedTask;
if (feature != null)
{
bindingContext.Result = ModelBindingResult.Success(feature.MatchedVersion);
}

return Task.CompletedTask;
}
}
Loading

0 comments on commit bace320

Please sign in to comment.