Skip to content

Commit

Permalink
Update MediatR to 10, some chore work
Browse files Browse the repository at this point in the history
  • Loading branch information
Sebastian Kleinschmager committed Apr 5, 2022
1 parent 35cf0ea commit b347adc
Show file tree
Hide file tree
Showing 5 changed files with 183 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
<PackageLicenseExpression></PackageLicenseExpression>
<Copyright>Copyright Sebastian Kleinschmager</Copyright>
<PackageLicenseFile>LICENSE</PackageLicenseFile>
<Version>4.0.0</Version>
<Version>5.0.0</Version>

<PublishRepositoryUrl>true</PublishRepositoryUrl>
<EmbedUntrackedSources>true</EmbedUntrackedSources>
Expand All @@ -37,7 +37,7 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="MediatR.Extensions.Microsoft.DependencyInjection" Version="[9.0.0, 10.0.0)" />
<PackageReference Include="MediatR.Extensions.Microsoft.DependencyInjection" Version="10.0.1" />
</ItemGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@

using System.Runtime.CompilerServices;
using Microsoft.AspNetCore.Http;

namespace MediatR.Extensions.Microsoft.AspNetCore.Mediator;
Expand Down Expand Up @@ -36,11 +36,26 @@ public async Task<TResponse> Send<TResponse>(IRequest<TResponse> request, Cancel
public async Task<object?> Send(object request, CancellationToken cancellationToken = default)
{
return await PossiblyWrapSendCallWithLinkedCancellationToken(
async token => await _mediator.Send(request, token).ConfigureAwait(false),
cancellationToken)
async token => await _mediator.Send(request, token).ConfigureAwait(false),
cancellationToken)
.ConfigureAwait(false);
}

public IAsyncEnumerable<TResponse> CreateStream<TResponse>(IStreamRequest<TResponse> request,
CancellationToken cancellationToken = default)
{
return PossiblyWrapCreateStreamCallWithNewCancellationToken(
token => _mediator.CreateStream(request, token),
cancellationToken);
}

public IAsyncEnumerable<object?> CreateStream(object request, CancellationToken cancellationToken = default)
{
return PossiblyWrapCreateStreamCallWithNewCancellationToken(
token => _mediator.CreateStream(request, token),
cancellationToken);
}

public async Task Publish(object notification, CancellationToken cancellationToken = default)
{
await PossiblyWrapPublishCallWithNewCancellationToken(
Expand Down Expand Up @@ -73,6 +88,35 @@ private async Task<TResponse> PossiblyWrapSendCallWithLinkedCancellationToken<TR
return await wrappedSend(cancellationToken).ConfigureAwait(false);
}

private async IAsyncEnumerable<TResponse> PossiblyWrapCreateStreamCallWithNewCancellationToken<TResponse>(
Func<CancellationToken, IAsyncEnumerable<TResponse>> wrappedCreateStream,
[EnumeratorCancellation] CancellationToken cancellationToken)
{
if (cancellationToken != default && _httpContextAccessor.HttpContext != null)
{
using var cancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, _httpContextAccessor.HttpContext.RequestAborted);
var token = cancellationTokenSource.Token;
await foreach (var value in wrappedCreateStream(token).ConfigureAwait(false))
{
yield return value;
}
}
else if (cancellationToken == default && _httpContextAccessor.HttpContext != null)
{
await foreach (var value in wrappedCreateStream(_httpContextAccessor.HttpContext.RequestAborted).ConfigureAwait(false))
{
yield return value;
}
}
else
{
await foreach (var value in wrappedCreateStream(cancellationToken).ConfigureAwait(false))
{
yield return value;
}
}
}

private async Task PossiblyWrapPublishCallWithNewCancellationToken(Func<CancellationToken, Task> wrappedPublish, CancellationToken cancellationToken)
{
if (cancellationToken != default && _httpContextAccessor.HttpContext != null)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,22 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="FluentAssertions" Version="6.2.0" />
<PackageReference Include="MediatR.Extensions.Microsoft.DependencyInjection" Version="9.0.0" />
<PackageReference Include="NSubstitute" Version="4.2.2" />
<PackageReference Include="nunit" Version="3.13.2" />
<PackageReference Include="NUnit3TestAdapter" Version="4.1.0">
<PackageReference Include="FluentAssertions" Version="6.6.0" />
<PackageReference Include="MediatR.Extensions.Microsoft.DependencyInjection" Version="10.0.1" />
<PackageReference Include="NSubstitute" Version="4.3.0" />
<PackageReference Include="nunit" Version="3.13.3" />
<PackageReference Include="NUnit3TestAdapter" Version="4.2.1">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.1.0" />
</ItemGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,11 @@ public void SetUp()
_subject = new RequestAbortedCancellationTokenMediatorDecorator(_mediator, _httpContextAccessor);
}

private IHttpContextAccessor _httpContextAccessor;
private RequestAbortedCancellationTokenMediatorDecorator _subject;
private HttpContext _httpContextStub;
private IMediator _mediator;
private CancellationTokenSource _requestAbortedTokenSource;
private IHttpContextAccessor _httpContextAccessor = null!;
private RequestAbortedCancellationTokenMediatorDecorator _subject = null!;
private HttpContext _httpContextStub = null!;
private IMediator _mediator = null!;
private CancellationTokenSource _requestAbortedTokenSource = null!;

[Test]
public async Task Strongly_typed_Send_uses_requested_aborted_cancellation_token_if_it_is_available_and_no_explicit_token_was_passed()
Expand Down Expand Up @@ -64,7 +64,7 @@ public async Task Strongly_typed_Send_falls_back_to_passed_cancellation_token_if
{
var fakeRequest = Substitute.For<IRequest<object>>();
var cancellationToken = new CancellationTokenSource().Token;
_httpContextAccessor.HttpContext.Returns((HttpContext)null);
_httpContextAccessor.HttpContext.Returns((HttpContext?)null);

await _subject.Send(fakeRequest, cancellationToken);

Expand Down Expand Up @@ -108,13 +108,113 @@ public async Task Object_typed_Send_falls_back_to_passed_cancellation_token_if_n
{
var fakeRequest = new object();
var cancellationToken = new CancellationTokenSource().Token;
_httpContextAccessor.HttpContext.Returns((HttpContext)null);
_httpContextAccessor.HttpContext.Returns((HttpContext?)null);

await _subject.Send(fakeRequest, cancellationToken);

await _mediator.Received(1).Send(fakeRequest, cancellationToken);
}

[Test]
public async Task Strongly_typed_CreateStream_uses_requested_aborted_cancellation_token_if_it_is_available_and_no_explicit_token_was_passed()
{
var fakeRequest = Substitute.For<IStreamRequest<object>>();

await foreach (var _ in _subject.CreateStream(fakeRequest))
{
}

_ = _mediator.Received(1).CreateStream(fakeRequest, _httpContextStub.RequestAborted);
}

[Test]
[TestCase("cancelByRequestAbortedToken")]
[TestCase("cancelByPassedToken")]
public async Task Strongly_typed_CreateStream_merges_passed_cancellation_token_with_request_aborted_token_if_both_are_set(string cancellationSource)
{
var fakeRequest = Substitute.For<IStreamRequest<object>>();
var cancellationTokenSource = new CancellationTokenSource();
var cancellationToken = cancellationTokenSource.Token;

await foreach (var _ in _subject.CreateStream(fakeRequest, cancellationToken))
{
}

_ = _mediator.Received(1).CreateStream(fakeRequest, Arg.Do<CancellationToken>(t =>
{
t.IsCancellationRequested.Should().BeFalse();
if (cancellationSource == "cancelByRequestAbortedToken")
_requestAbortedTokenSource.Cancel();
else if (cancellationSource == "cancelByPassedToken")
cancellationTokenSource.Cancel();
t.IsCancellationRequested.Should().BeTrue();
}));
}

[Test]
public async Task Strongly_typed_CreateStream_falls_back_to_passed_cancellation_token_if_no_http_context_or_request_aborted_token_is_available()
{
var fakeRequest = Substitute.For<IStreamRequest<object>>();
var cancellationToken = new CancellationTokenSource().Token;
_httpContextAccessor.HttpContext.Returns((HttpContext?)null);

await foreach (var _ in _subject.CreateStream(fakeRequest, cancellationToken))
{
}

_ = _mediator.Received(1).CreateStream(fakeRequest, cancellationToken);
}

[Test]
public async Task Object_typed_CreateStream_uses_requested_aborted_cancellation_token_if_it_is_available_and_no_explicit_token_was_passed()
{
var fakeRequest = new object();

await foreach (var _ in _subject.CreateStream(fakeRequest))
{
}

_ = _mediator.Received(1).CreateStream(fakeRequest, _httpContextStub.RequestAborted);
}

[Test]
[TestCase("cancelByRequestAbortedToken")]
[TestCase("cancelByPassedToken")]
public async Task Object_typed_CreateStream_merges_passed_cancellation_token_with_request_aborted_token_if_both_are_set(string cancellationSource)
{
var fakeRequest = new object();
var cancellationTokenSource = new CancellationTokenSource();
var cancellationToken = cancellationTokenSource.Token;

await foreach (var _ in _subject.CreateStream(fakeRequest, cancellationToken))
{
}

_ = _mediator.Received(1).CreateStream(fakeRequest, Arg.Do<CancellationToken>(t =>
{
t.IsCancellationRequested.Should().BeFalse();
if (cancellationSource == "cancelByRequestAbortedToken")
_requestAbortedTokenSource.Cancel();
else if (cancellationSource == "cancelByPassedToken")
cancellationTokenSource.Cancel();
t.IsCancellationRequested.Should().BeTrue();
}));
}

[Test]
public async Task Object_typed_CreateStream_falls_back_to_passed_cancellation_token_if_no_http_context_or_request_aborted_token_is_available()
{
var fakeRequest = new object();
var cancellationToken = new CancellationTokenSource().Token;
_httpContextAccessor.HttpContext.Returns((HttpContext?)null);

await foreach (var _ in _subject.CreateStream(fakeRequest, cancellationToken))
{
}

_ = _mediator.Received(1).CreateStream(fakeRequest, cancellationToken);
}

[Test]
public async Task Strongly_typed_Publish_uses_requested_aborted_cancellation_token_if_available()
{
Expand Down Expand Up @@ -151,7 +251,7 @@ await _mediator.Received(1).Publish(fakeNotification, Arg.Do<CancellationToken>(
public async Task Strongly_typed_Publish_falls_back_to_passed_cancellation_token_if_no_http_context_or_request_aborted_token_is_available()
{
var fakeNotification = Substitute.For<INotification>();
_httpContextAccessor.HttpContext.Returns((HttpContext)null);
_httpContextAccessor.HttpContext.Returns((HttpContext?)null);
var cancellationToken = new CancellationTokenSource().Token;

await _subject.Publish(fakeNotification, cancellationToken);
Expand Down Expand Up @@ -195,7 +295,7 @@ await _mediator.Received(1).Publish(fakeNotification, Arg.Do<CancellationToken>(
public async Task Object_typed_Publish_falls_back_to_passed_cancellation_token_if_no_http_context_or_request_aborted_token_is_available()
{
var fakeNotification = new object();
_httpContextAccessor.HttpContext.Returns((HttpContext)null);
_httpContextAccessor.HttpContext.Returns((HttpContext?)null);
var cancellationToken = new CancellationTokenSource().Token;

await _subject.Publish(fakeNotification, cancellationToken);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using NUnit.Framework;

namespace MediatR.Extensions.Microsoft.AspNetCore.Tests;

[TestFixture]
public class ServiceRegistrationTests
{
Expand Down Expand Up @@ -71,27 +72,38 @@ public void Test_type_handler_service_registration_extension_method_with_configu
[ExcludeFromCodeCoverage]
public class MyFakeMediator : IMediator
{
public object ReceivedRequest { get; private set; }
public object? ReceivedRequest { get; private set; }

public Task<TResponse> Send<TResponse>(IRequest<TResponse> request, CancellationToken cancellationToken = default)
{
ReceivedRequest = request;
return Task.FromResult((TResponse)new object());
}

public Task<object> Send(object request, CancellationToken cancellationToken = default)
public Task<object?> Send(object request, CancellationToken cancellationToken = default)
{
throw new NotImplementedException();
}

public IAsyncEnumerable<TResponse> CreateStream<TResponse>(IStreamRequest<TResponse> request,
CancellationToken cancellationToken = default)
{
throw new NotImplementedException();
}

public IAsyncEnumerable<object?> CreateStream(object request, CancellationToken cancellationToken = default)
{
throw new System.NotImplementedException();
throw new NotImplementedException();
}

public Task Publish(object notification, CancellationToken cancellationToken = default)
{
throw new System.NotImplementedException();
throw new NotImplementedException();
}

public Task Publish<TNotification>(TNotification notification, CancellationToken cancellationToken = default) where TNotification : INotification
{
throw new System.NotImplementedException();
throw new NotImplementedException();
}
}

Expand Down

0 comments on commit b347adc

Please sign in to comment.