Skip to content

Commit

Permalink
feat(csharp): nullability support (#57)
Browse files Browse the repository at this point in the history
* feat(csharp): nullability support

* fix editorconfig namings for static readonly and const

* update changelog + bump

* remove middleware builder from nullable
  • Loading branch information
stephenlautier committed Dec 6, 2019
1 parent b78c330 commit f060b3d
Show file tree
Hide file tree
Showing 37 changed files with 171 additions and 157 deletions.
18 changes: 17 additions & 1 deletion .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ dotnet_code_quality_unused_parameters = all:suggestion

# var preferences
csharp_style_var_elsewhere = true:suggestion
csharp_style_var_for_built_in_types = false:suggestion
csharp_style_var_for_built_in_types = true:suggestion
csharp_style_var_when_type_is_apparent = true:suggestion

# Expression-bodied members
Expand Down Expand Up @@ -173,6 +173,14 @@ dotnet_naming_rule.types_should_be_pascal_case.severity = suggestion
dotnet_naming_rule.types_should_be_pascal_case.symbols = types
dotnet_naming_rule.types_should_be_pascal_case.style = pascal_case

dotnet_naming_rule.static_fieldprop_pascal_case.severity = suggestion
dotnet_naming_rule.static_fieldprop_pascal_case.symbols = static_fieldprop
dotnet_naming_rule.static_fieldprop_pascal_case.style = pascal_case

dotnet_naming_rule.const_fieldprop.severity = suggestion
dotnet_naming_rule.const_fieldprop.symbols = const_fieldprop
dotnet_naming_rule.const_fieldprop.style = pascal_case

dotnet_naming_rule.non_field_members_should_be_pascal_case.severity = suggestion
dotnet_naming_rule.non_field_members_should_be_pascal_case.symbols = non_field_members
dotnet_naming_rule.non_field_members_should_be_pascal_case.style = pascal_case
Expand All @@ -187,6 +195,14 @@ dotnet_naming_symbols.interface.applicable_kinds = interface
dotnet_naming_symbols.interface.applicable_accessibilities = public, internal, private, protected, protected_internal
dotnet_naming_symbols.interface.required_modifiers =

dotnet_naming_symbols.static_fieldprop.applicable_kinds = field, property
dotnet_naming_symbols.static_fieldprop.applicable_accessibilities = private, public, internal
dotnet_naming_symbols.static_fieldprop.required_modifiers = static, readonly

dotnet_naming_symbols.const_fieldprop.applicable_kinds = field, property
dotnet_naming_symbols.const_fieldprop.applicable_accessibilities = private, public, internal
dotnet_naming_symbols.const_fieldprop.required_modifiers = const

dotnet_naming_symbols.private_or_internal_static_field.applicable_kinds = field
dotnet_naming_symbols.private_or_internal_static_field.applicable_accessibilities = internal, private
dotnet_naming_symbols.private_or_internal_static_field.required_modifiers = static
Expand Down
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

[_vNext_](https://github.com/sketch7/FluentlyHttpClient/compare/3.6.0...3.7.0) (2019-X-X)

## [3.8.0](https://github.com/sketch7/FluentlyHttpClient/compare/3.7.2...3.8.0) (2019-12-x)

### Features

- **csharp:** initial nullability support

## [3.7.2](https://github.com/sketch7/FluentlyHttpClient/compare/3.7.1...3.7.2) (2019-10-08)

### Bug Fixes
Expand Down
9 changes: 7 additions & 2 deletions FluentlyHttpClient.sln
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.27130.2036
# Visual Studio Version 16
VisualStudioVersion = 16.0.29519.87
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "docs", "docs", "{1D373993-0345-466C-B421-6B8336E3D40E}"
ProjectSection(SolutionItems) = preProject
Expand Down Expand Up @@ -38,6 +38,11 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FluentlyHttpClient.Sample.A
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{EF87A44F-A75B-4C2F-86CD-402EBB8D0F3F}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{AC26155F-CB0B-4794-857A-5AE9BFEE04C3}"
ProjectSection(SolutionItems) = preProject
.editorconfig = .editorconfig
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down
4 changes: 2 additions & 2 deletions benchmark/Benchmarking.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ namespace FluentlyHttpClient.Benchmarks
[MemoryDiagnoser]
public class Benchmarking
{
private IFluentHttpClient _jsonHttpClient;
private IFluentHttpClient _messagePackHttpClient;
private IFluentHttpClient? _jsonHttpClient;
private IFluentHttpClient? _messagePackHttpClient;

private IServiceProvider BuildContainer()
{
Expand Down
3 changes: 1 addition & 2 deletions benchmark/FluentlyHttpClient.Benchmarks.csproj
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.2</TargetFramework>
<IsPackable>false</IsPackable>
<LangVersion>latest</LangVersion>
</PropertyGroup>

<ItemGroup>
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@sketch7/fluently-http-client",
"version": "3.7.3",
"version": "3.8.0",
"versionSuffix": "",
"scripts": {
"pack": "bash ./tools/pack.sh",
Expand Down
12 changes: 3 additions & 9 deletions src/FluentlyHttpClient.Entity/FluentHttpClientDbContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ public FluentHttpClientDbContext(DbContextOptions options)
: base(options)
{ }

public DbSet<HttpResponseEntity> HttpResponses { get; set; }
public DbSet<HttpResponseEntity> HttpResponses { get; set; } = null!;

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
Expand All @@ -19,14 +19,8 @@ protected override void OnModelCreating(ModelBuilder modelBuilder)
modelBuilder.ApplyConfigurationsFromAssembly(Assembly.GetExecutingAssembly());
}

public Task Initialize()
{
return Database.MigrateAsync();
}
public Task Initialize() => Database.MigrateAsync();

public Task Commit()
{
return SaveChangesAsync();
}
public Task Commit() => SaveChangesAsync();
}
}
20 changes: 10 additions & 10 deletions src/FluentlyHttpClient.Entity/HttpResponseEntity.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,16 @@ namespace FluentlyHttpClient.Entity
{
public class HttpResponseEntity : IHttpResponseStore
{
public string Id { get; set; }
public string Name { get; set; }
public string Hash { get; set; }
public string Url { get; set; }
public string Content { get; set; }
public FluentHttpHeaders Headers { get; set; }
public string? Id { get; set; }
public string? Name { get; set; }
public string? Hash { get; set; }
public string? Url { get; set; }
public string? Content { get; set; }
public FluentHttpHeaders? Headers { get; set; }
public int StatusCode { get; set; }
public string ReasonPhrase { get; set; }
public string Version { get; set; }
public FluentHttpHeaders ContentHeaders { get; set; }
public HttpRequestMessage RequestMessage { get; set; }
public string? ReasonPhrase { get; set; }
public string? Version { get; set; }
public FluentHttpHeaders? ContentHeaders { get; set; }
public HttpRequestMessage? RequestMessage { get; set; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ IMemoryCache cache
_cache = cache;
}

public async Task<FluentHttpResponse> Get(string hash)
public async Task<FluentHttpResponse?> Get(string hash)
{
var id = await hash.ComputeHash();
var result = await _cache.GetOrCreate(id, async _ =>
Expand Down
3 changes: 1 addition & 2 deletions src/FluentlyHttpClient.Entity/ServiceCollectionExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,13 @@ public static IServiceCollection AddFluentlyHttpClientEntity(this IServiceCollec
MaxPoolSize = 600,
MinPoolSize = 5
};

return services.AddFluentlyHttpClientEntity(conn, builder => builder.EnableRetryOnFailure());
}

public static IServiceCollection AddFluentlyHttpClientEntity(
this IServiceCollection services,
SqlConnectionStringBuilder connectionStringBuilder,
Action<SqlServerDbContextOptionsBuilder> builder = null
Action<SqlServerDbContextOptionsBuilder>? builder = null
)
{
if (connectionStringBuilder == null)
Expand Down
36 changes: 18 additions & 18 deletions src/FluentlyHttpClient/Caching/HttpResponseStore.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,29 +4,29 @@ namespace FluentlyHttpClient.Caching
{
public interface IHttpResponseStore
{
string Name { get; set; }
string Hash { get; set; }
string Url { get; set; }
string Content { get; set; }
FluentHttpHeaders Headers { get; set; }
string? Name { get; set; }
string? Hash { get; set; }
string? Url { get; set; }
string? Content { get; set; }
FluentHttpHeaders? Headers { get; set; }
int StatusCode { get; set; }
string ReasonPhrase { get; set; }
string Version { get; set; }
FluentHttpHeaders ContentHeaders { get; set; }
HttpRequestMessage RequestMessage { get; set; }
string? ReasonPhrase { get; set; }
string? Version { get; set; }
FluentHttpHeaders? ContentHeaders { get; set; }
HttpRequestMessage? RequestMessage { get; set; }
}

public class HttpResponseStore : IHttpResponseStore
{
public string Name { get; set; }
public string Hash { get; set; }
public string Url { get; set; }
public string Content { get; set; }
public FluentHttpHeaders Headers { get; set; }
public string? Name { get; set; }
public string? Hash { get; set; }
public string? Url { get; set; }
public string? Content { get; set; }
public FluentHttpHeaders? Headers { get; set; }
public int StatusCode { get; set; }
public string ReasonPhrase { get; set; }
public string Version { get; set; }
public FluentHttpHeaders ContentHeaders { get; set; }
public HttpRequestMessage RequestMessage { get; set; }
public string? ReasonPhrase { get; set; }
public string? Version { get; set; }
public FluentHttpHeaders? ContentHeaders { get; set; }
public HttpRequestMessage? RequestMessage { get; set; }
}
}
12 changes: 6 additions & 6 deletions src/FluentlyHttpClient/Caching/ResponseCacheMiddleware.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public class ResponseCacheHttpMiddlewareOptions
/// Ignore the request from being cached.
/// </summary>
public bool ShouldIgnore { get; set; }
public Predicate<FluentHttpRequest> Matcher { get; set; }
public Predicate<FluentHttpRequest>? Matcher { get; set; }

/// <summary>
/// Don't attempt to read from the cache but write only. This is useful to start and populating data.
Expand Down Expand Up @@ -61,7 +61,7 @@ public async Task<FluentHttpResponse> Invoke(FluentHttpMiddlewareContext context
if (options.ShouldIgnore || options.Matcher != null && !options.Matcher(request))
return await _next(context);
var hash = request.GetHash();
FluentHttpResponse response = null;
FluentHttpResponse? response = null;

if (!options.IsWriteOnly)
response = await _service.Get(hash);
Expand Down Expand Up @@ -111,7 +111,7 @@ public static FluentHttpRequestBuilder WithResponseCachingOptions(this FluentHtt
/// </summary>
/// <param name="requestBuilder">Request builder instance.</param>
/// <param name="configure">Action to configure options.</param>
public static FluentHttpRequestBuilder WithResponseCachingOptions(this FluentHttpRequestBuilder requestBuilder, Action<ResponseCacheHttpMiddlewareOptions> configure)
public static FluentHttpRequestBuilder WithResponseCachingOptions(this FluentHttpRequestBuilder requestBuilder, Action<ResponseCacheHttpMiddlewareOptions>? configure)
{
var options = new ResponseCacheHttpMiddlewareOptions();
configure?.Invoke(options);
Expand All @@ -124,7 +124,7 @@ public static FluentHttpRequestBuilder WithResponseCachingOptions(this FluentHtt
/// <param name="request">Request to get options from.</param>
/// <param name="defaultOptions"></param>
/// <returns>Returns merged logging options.</returns>
public static ResponseCacheHttpMiddlewareOptions GetResponseCachingOptions(this FluentHttpRequest request, ResponseCacheHttpMiddlewareOptions defaultOptions = null)
public static ResponseCacheHttpMiddlewareOptions? GetResponseCachingOptions(this FluentHttpRequest request, ResponseCacheHttpMiddlewareOptions? defaultOptions = null)
{
if (!request.Items.TryGetValue(OptionsKey, out var result)) return defaultOptions;
var options = (ResponseCacheHttpMiddlewareOptions)result;
Expand All @@ -141,15 +141,15 @@ public static ResponseCacheHttpMiddlewareOptions GetResponseCachingOptions(this
/// </summary>
/// <param name="builder">Builder instance</param>
/// <param name="options"></param>
public static FluentHttpClientBuilder UseResponseCaching(this FluentHttpClientBuilder builder, ResponseCacheHttpMiddlewareOptions options = null)
public static FluentHttpClientBuilder UseResponseCaching(this FluentHttpClientBuilder builder, ResponseCacheHttpMiddlewareOptions? options = null)
=> builder.UseMiddleware<ResponseCacheHttpMiddleware>(options ?? new ResponseCacheHttpMiddlewareOptions());

/// <summary>
/// Use response caching middleware which get from cache or get from remote and cache responses.
/// </summary>
/// <param name="builder">Builder instance</param>
/// <param name="configure">Action to configure caching options.</param>
public static FluentHttpClientBuilder UseResponseCaching(this FluentHttpClientBuilder builder, Action<ResponseCacheHttpMiddlewareOptions> configure)
public static FluentHttpClientBuilder UseResponseCaching(this FluentHttpClientBuilder builder, Action<ResponseCacheHttpMiddlewareOptions>? configure)
{
var options = new ResponseCacheHttpMiddlewareOptions();
configure?.Invoke(options);
Expand Down
6 changes: 3 additions & 3 deletions src/FluentlyHttpClient/Caching/ResponseCacheService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ namespace FluentlyHttpClient.Caching
{
public interface IResponseCacheService
{
Task<FluentHttpResponse> Get(string hash);
Task<FluentHttpResponse?> Get(string hash);
Task Set(string hash, FluentHttpResponse response);
}

Expand All @@ -18,10 +18,10 @@ public MemoryResponseCacheService(IMemoryCache cache)
_cache = cache;
}

public Task<FluentHttpResponse> Get(string hash)
public Task<FluentHttpResponse?> Get(string hash)
{
var result = _cache.Get<FluentHttpResponse>(hash);
return result?.Clone() ?? Task.FromResult<FluentHttpResponse>(null);
return result?.Clone() ?? Task.FromResult<FluentHttpResponse?>(null);
}

public Task Set(string hash, FluentHttpResponse response)
Expand Down
8 changes: 4 additions & 4 deletions src/FluentlyHttpClient/FluentHttpClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,15 +49,15 @@ public interface IFluentHttpClient : IDisposable
/// <summary>Get the formatter for an HTTP content type.</summary>
/// <param name="contentType">The HTTP content type (or <c>null</c> to automatically select one).</param>
/// <exception cref="InvalidOperationException">No MediaTypeFormatters are available on the API client for this content type.</exception>
MediaTypeFormatter GetFormatter(MediaTypeHeaderValue contentType = null);
MediaTypeFormatter GetFormatter(MediaTypeHeaderValue? contentType = null);

/// <summary>
/// Create a new request builder which can be configured fluently.
/// </summary>
/// <param name="uriTemplate">Uri resource template e.g. <c>"/org/{id}"</c></param>
/// <param name="interpolationData">Data to interpolate within the Uri template place holders e.g. <c>{id}</c>. Can be either dictionary or object.</param>
/// <returns>Returns a new request builder.</returns>
FluentHttpRequestBuilder CreateRequest(string uriTemplate = null, object interpolationData = null);
FluentHttpRequestBuilder CreateRequest(string? uriTemplate = null, object? interpolationData = null);

/// <summary>
/// Creates a new client and inherit options from the current.
Expand Down Expand Up @@ -153,7 +153,7 @@ IServiceProvider serviceProvider
}

/// <inheritdoc />
public MediaTypeFormatter GetFormatter(MediaTypeHeaderValue contentType = null)
public MediaTypeFormatter GetFormatter(MediaTypeHeaderValue? contentType = null)
{
if (!Formatters.Any())
throw new InvalidOperationException("No media type formatters available.");
Expand All @@ -168,7 +168,7 @@ public MediaTypeFormatter GetFormatter(MediaTypeHeaderValue contentType = null)
}

/// <inheritdoc />
public FluentHttpRequestBuilder CreateRequest(string uriTemplate = null, object interpolationData = null)
public FluentHttpRequestBuilder CreateRequest(string? uriTemplate = null, object? interpolationData = null)
{
var builder = ActivatorUtilities.CreateInstance<FluentHttpRequestBuilder>(_serviceProvider, this);
_requestBuilderDefaults?.Invoke(builder);
Expand Down

0 comments on commit f060b3d

Please sign in to comment.