Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Remove IHttpControllerActivator.Release()

  • Loading branch information...
commit 8ad1c88269b1abd44713b239410f723fd5559ef0 1 parent 0602800
@bradwilson bradwilson authored
View
9 src/System.Web.Http/ApiController.cs
@@ -124,8 +124,15 @@ public virtual Task<HttpResponseMessage> ExecuteAsync(HttpControllerContext cont
}
Initialize(controllerContext);
- HttpControllerDescriptor controllerDescriptor = controllerContext.ControllerDescriptor;
+ // We can't be reused, and we know we're disposable, so make sure we go away when
+ // the request has been completed.
+ if (_request != null)
+ {
+ _request.RegisterForDispose(this);
+ }
+
+ HttpControllerDescriptor controllerDescriptor = controllerContext.ControllerDescriptor;
HttpActionDescriptor actionDescriptor = controllerDescriptor.HttpActionSelector.SelectAction(controllerContext);
HttpActionContext actionContext = new HttpActionContext(controllerContext, actionDescriptor);
View
21 src/System.Web.Http/Controllers/HttpControllerDescriptor.cs
@@ -173,27 +173,6 @@ public virtual IHttpController CreateController(HttpRequestMessage request)
}
/// <summary>
- /// Releases an <see cref="IHttpController"/> instance.
- /// </summary>
- /// <param name="controllerContext">The controller context.</param>
- /// <param name="controller">The controller.</param>
- public virtual void ReleaseController(IHttpController controller, HttpControllerContext controllerContext)
- {
- if (controller == null)
- {
- throw Error.ArgumentNull("controller");
- }
-
- if (controllerContext == null)
- {
- throw Error.ArgumentNull("controllerContext");
- }
-
- // just delegate the work to the activator
- HttpControllerActivator.Release(controller, controllerContext);
- }
-
- /// <summary>
/// Returns the collection of <see cref="IFilter">filters</see> associated with this descriptor's controller.
/// </summary>
/// <remarks>The default implementation calls <see cref="GetCustomAttributes{IFilter}()"/>.</remarks>
View
24 src/System.Web.Http/Dispatcher/DefaultHttpControllerActivator.cs
@@ -85,29 +85,5 @@ public IHttpController Create(HttpRequestMessage request, HttpControllerDescript
throw Error.InvalidOperation(ex, SRResources.DefaultControllerFactory_ErrorCreatingController, controllerType.Name);
}
}
-
- /// <summary>
- /// Releases the <paramref name="controller"/> instance
- /// </summary>
- /// <param name="controllerContext">The <see cref="HttpControllerContext"/> containing </param>
- /// <param name="controller">The <see cref="IHttpController"/> that is to be released</param>
- public void Release(IHttpController controller, HttpControllerContext controllerContext)
- {
- if (controller == null)
- {
- throw Error.ArgumentNull("controller");
- }
-
- if (controllerContext == null)
- {
- throw Error.ArgumentNull("controllerContext");
- }
-
- IDisposable disposable = controller as IDisposable;
- if (disposable != null)
- {
- disposable.Dispose();
- }
- }
}
}
View
13 src/System.Web.Http/Dispatcher/HttpControllerDispatcher.cs
@@ -157,18 +157,7 @@ private Task<HttpResponseMessage> SendAsyncInternal(HttpRequestMessage request,
controllerContext.Controller = httpController;
controllerContext.ControllerDescriptor = httpControllerDescriptor;
- try
- {
- return httpController.ExecuteAsync(controllerContext, cancellationToken).Finally(() =>
- {
- httpControllerDescriptor.ReleaseController(httpController, controllerContext);
- });
- }
- catch
- {
- httpControllerDescriptor.ReleaseController(httpController, controllerContext);
- throw;
- }
+ return httpController.ExecuteAsync(controllerContext, cancellationToken);
}
[SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "Caller owns HttpResponseMessage instance.")]
View
2  src/System.Web.Http/Dispatcher/IHttpControllerActivator.cs
@@ -9,7 +9,5 @@ namespace System.Web.Http.Dispatcher
public interface IHttpControllerActivator
{
IHttpController Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType);
-
- void Release(IHttpController controller, HttpControllerContext controllerContext);
}
}
View
23 src/System.Web.Http/Tracing/Tracers/HttpControllerActivatorTracer.cs
@@ -11,7 +11,6 @@ namespace System.Web.Http.Tracing.Tracers
internal class HttpControllerActivatorTracer : IHttpControllerActivator
{
private const string CreateMethodName = "Create";
- private const string ReleaseMethodName = "Release";
private readonly IHttpControllerActivator _innerActivator;
private readonly ITraceWriter _traceWriter;
@@ -46,30 +45,10 @@ IHttpController IHttpControllerActivator.Create(HttpRequestMessage request, Http
if (controller != null && !(controller is HttpControllerTracer))
{
- controller = new HttpControllerTracer(controller, _traceWriter);
+ controller = new HttpControllerTracer(request, controller, _traceWriter);
}
return controller;
}
-
- void IHttpControllerActivator.Release(IHttpController controller, HttpControllerContext controllerContext)
- {
- _traceWriter.TraceBeginEnd(
- controllerContext.Request,
- TraceCategories.ControllersCategory,
- TraceLevel.Info,
- _innerActivator.GetType().Name,
- ReleaseMethodName,
- beginTrace: (tr) =>
- {
- tr.Message = controller == null ? SRResources.TraceNoneObjectMessage : controller.GetType().FullName;
- },
- execute: () =>
- {
- _innerActivator.Release(controller, controllerContext);
- },
- endTrace: null,
- errorTrace: null);
- }
}
}
View
28 src/System.Web.Http/Tracing/Tracers/HttpControllerDescriptorTracer.cs
@@ -1,4 +1,5 @@
-using System.Net.Http;
+using System.Diagnostics.CodeAnalysis;
+using System.Net.Http;
using System.Web.Http.Controllers;
using System.Web.Http.Properties;
@@ -10,7 +11,6 @@ namespace System.Web.Http.Tracing.Tracers
internal class HttpControllerDescriptorTracer : HttpControllerDescriptor
{
private const string CreateControllerMethodName = "CreateController";
- private const string ReleaseControllerMethodName = "ReleaseController";
private readonly HttpControllerDescriptor _innerDescriptor;
private readonly ITraceWriter _traceWriter;
@@ -22,6 +22,7 @@ public HttpControllerDescriptorTracer(HttpConfiguration configuration, string co
_traceWriter = traceWriter;
}
+ [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "This object is returned back to the caller")]
public override IHttpController CreateController(HttpRequestMessage request)
{
IHttpController controller = null;
@@ -47,31 +48,10 @@ public override IHttpController CreateController(HttpRequestMessage request)
if (controller != null && !(controller is HttpControllerTracer))
{
- return new HttpControllerTracer(controller, _traceWriter);
+ return new HttpControllerTracer(request, controller, _traceWriter);
}
return controller;
}
-
- public override void ReleaseController(IHttpController controller, HttpControllerContext controllerContext)
- {
- _traceWriter.TraceBeginEnd(
- controllerContext.Request,
- TraceCategories.ControllersCategory,
- TraceLevel.Info,
- _innerDescriptor.GetType().Name,
- ReleaseControllerMethodName,
- beginTrace: (tr) =>
- {
- tr.Message = HttpControllerTracer.ActualControllerType(controller).FullName;
- },
- execute: () =>
- {
- IHttpController actualController = HttpControllerTracer.ActualController(controller);
- _innerDescriptor.ReleaseController(actualController, controllerContext);
- },
- endTrace: null,
- errorTrace: null);
- }
}
}
View
49 src/System.Web.Http/Tracing/Tracers/HttpControllerTracer.cs
@@ -1,26 +1,49 @@
-using System.Net.Http;
+using System.Collections.Generic;
+using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using System.Web.Http.Controllers;
+using System.Web.Http.Hosting;
namespace System.Web.Http.Tracing.Tracers
{
/// <summary>
/// Tracer for <see cref="IHttpController"/>.
/// </summary>
- internal class HttpControllerTracer : IHttpController
+ internal class HttpControllerTracer : IHttpController, IDisposable
{
+ private const string DisposeMethodName = "Dispose";
private const string ExecuteAsyncMethodName = "ExecuteAsync";
private readonly IHttpController _innerController;
+ private readonly HttpRequestMessage _request;
private readonly ITraceWriter _traceWriter;
- public HttpControllerTracer(IHttpController innerController, ITraceWriter traceWriter)
+ public HttpControllerTracer(HttpRequestMessage request, IHttpController innerController, ITraceWriter traceWriter)
{
_innerController = innerController;
+ _request = request;
_traceWriter = traceWriter;
}
+ void IDisposable.Dispose()
+ {
+ IDisposable disposable = _innerController as IDisposable;
+ if (disposable != null)
+ {
+ _traceWriter.TraceBeginEnd(
+ _request,
+ TraceCategories.ControllersCategory,
+ TraceLevel.Info,
+ _innerController.GetType().Name,
+ DisposeMethodName,
+ beginTrace: null,
+ execute: disposable.Dispose,
+ endTrace: null,
+ errorTrace: null);
+ }
+ }
+
Task<HttpResponseMessage> IHttpController.ExecuteAsync(HttpControllerContext controllerContext, CancellationToken cancellationToken)
{
return _traceWriter.TraceBeginEndAsync<HttpResponseMessage>(
@@ -34,7 +57,25 @@ Task<HttpResponseMessage> IHttpController.ExecuteAsync(HttpControllerContext con
{
// Critical to allow wrapped controller to have itself in ControllerContext
controllerContext.Controller = ActualController(controllerContext.Controller);
- return _innerController.ExecuteAsync(controllerContext, cancellationToken);
+ return _innerController.ExecuteAsync(controllerContext, cancellationToken)
+ .Finally(() =>
+ {
+ IDisposable disposable = _innerController as IDisposable;
+
+ if (disposable != null)
+ {
+ // Need to remove the original controller from the disposables list, if it's
+ // there, and put ourselves in there instead, so we can trace the dispose.
+ // This currently knows a little too much about how RegisterForDispose works,
+ // but that's unavoidable unless we want to offer UnregisterForDispose.
+ IList<IDisposable> disposables;
+ if (_request.Properties.TryGetValue(HttpPropertyKeys.DisposableRequestResourcesKey, out disposables))
+ {
+ disposables.Remove(disposable);
+ disposables.Add(this);
+ }
+ }
+ });
},
endTrace: (tr, response) =>
{
View
75 test/System.Web.Http.Integration.Test/Controllers/CustomControllerDescriptorTest.cs
@@ -1,75 +0,0 @@
-using System.Net;
-using System.Net.Http;
-using System.Web.Http.Dispatcher;
-using System.Web.Http.SelfHost;
-using Xunit;
-
-namespace System.Web.Http.Controllers
-{
- public class CustomControllerDescriptorTest
- {
- [Fact]
- public void Body_WithSingletonControllerInstance_Fails()
- {
- // Arrange
- HttpClient httpClient = new HttpClient();
- string baseAddress = "http://localhost";
- string requestUri = baseAddress + "/Test";
- HttpSelfHostConfiguration configuration = new HttpSelfHostConfiguration(baseAddress);
- configuration.Routes.MapHttpRoute("Default", "{controller}", new { controller = "Test" });
- configuration.Services.Replace(typeof(IHttpControllerSelector), new MySingletonControllerSelector(configuration));
- HttpSelfHostServer host = new HttpSelfHostServer(configuration);
- host.OpenAsync().Wait();
- HttpResponseMessage response = null;
-
- try
- {
- // Act
- response = httpClient.GetAsync(requestUri).Result;
- response = httpClient.GetAsync(requestUri).Result;
- response = httpClient.GetAsync(requestUri).Result;
-
- // Assert
- Assert.Equal(HttpStatusCode.InternalServerError, response.StatusCode);
- }
- finally
- {
- if (response != null)
- {
- response.Dispose();
- }
- }
-
- host.CloseAsync().Wait();
- }
-
- private class MySingletonControllerSelector : DefaultHttpControllerSelector
- {
- public MySingletonControllerSelector(HttpConfiguration configuration)
- : base(configuration)
- {
- }
-
- public override HttpControllerDescriptor SelectController(HttpRequestMessage request)
- {
- return new MySingletonControllerDescriptor();
- }
- }
-
- private class MySingletonControllerDescriptor : HttpControllerDescriptor
- {
- private static TestController singleton = new TestController();
-
- public override IHttpController CreateController(HttpRequestMessage request)
- {
- return singleton;
- }
-
- public override void ReleaseController(IHttpController controller, HttpControllerContext controllerContext)
- {
- // do nothing
- }
- }
-
- }
-}
View
1  test/System.Web.Http.Integration.Test/System.Web.Http.Integration.Test.csproj
@@ -105,7 +105,6 @@
<Compile Include="Controllers\Apis\TestController.cs" />
<Compile Include="Controllers\Apis\User.cs" />
<Compile Include="Controllers\Apis\UserAddress.cs" />
- <Compile Include="Controllers\CustomControllerDescriptorTest.cs" />
<Compile Include="Controllers\Helpers\ApiControllerHelper.cs" />
<Compile Include="ExceptionHandling\DuplicateControllers.cs" />
<Compile Include="ExceptionHandling\ExceptionController.cs" />
View
61 test/System.Web.Http.Test/Controllers/ApiControllerTest.cs
@@ -10,6 +10,7 @@
using System.Threading;
using System.Threading.Tasks;
using System.Web.Http.Controllers;
+using System.Web.Http.Dispatcher;
using System.Web.Http.Filters;
using System.Web.Http.ModelBinding;
using System.Web.Http.Routing;
@@ -664,6 +665,49 @@ public void User_ReturnsThreadPrincipal()
Assert.Same(result, principal);
}
+ [Fact]
+ public void ApiControllerCannotBeReused()
+ {
+ // Arrange
+ var config = new HttpConfiguration();
+ var singletonController = new Mock<ApiController> { CallBase = true }.Object;
+ var mockDescriptor = new Mock<HttpControllerDescriptor>(config, "MyMock", singletonController.GetType()) { CallBase = true };
+ mockDescriptor.Setup(d => d.CreateController(It.IsAny<HttpRequestMessage>())).Returns(singletonController);
+ var mockSelector = new Mock<DefaultHttpControllerSelector>(config) { CallBase = true };
+ mockSelector.Setup(s => s.SelectController(It.IsAny<HttpRequestMessage>())).Returns(mockDescriptor.Object);
+ config.Routes.MapHttpRoute("default", "", new { controller = "MyMock" });
+ config.Services.Replace(typeof(IHttpControllerSelector), mockSelector.Object);
+ var server = new HttpServer(config);
+ var invoker = new HttpMessageInvoker(server);
+
+ // Act
+ HttpResponseMessage response1 = invoker.SendAsync(new HttpRequestMessage(HttpMethod.Get, "http://localhost/"), CancellationToken.None).Result;
+ HttpResponseMessage response2 = invoker.SendAsync(new HttpRequestMessage(HttpMethod.Get, "http://localhost/"), CancellationToken.None).Result;
+
+ // Assert
+ Assert.NotEqual(HttpStatusCode.InternalServerError, response1.StatusCode);
+ Assert.Equal(HttpStatusCode.InternalServerError, response2.StatusCode);
+ Assert.Contains("Cannot reuse an 'ApiController' instance. 'ApiController' has to be constructed per incoming message.", response2.Content.ReadAsStringAsync().Result);
+ }
+
+ [Fact]
+ public void ApiControllerPutsSelfInRequestResourcesToBeDisposed()
+ {
+ // Arrange
+ var config = new HttpConfiguration();
+ config.Routes.MapHttpRoute("default", "", new { controller = "SpyDispose" });
+ var server = new HttpServer(config);
+ var invoker = new HttpMessageInvoker(server);
+ var request = new HttpRequestMessage(HttpMethod.Get, "http://localhost/");
+ invoker.SendAsync(request, CancellationToken.None).WaitUntilCompleted();
+
+ // Act
+ request.DisposeRequestResources();
+
+ // Assert
+ Assert.True(SpyDisposeController.DisposeWasCalled);
+ }
+
private Mock<IAuthorizationFilter> CreateAuthorizationFilterMock(Func<HttpActionContext, CancellationToken, Func<Task<HttpResponseMessage>>, Task<HttpResponseMessage>> implementation)
{
Mock<IAuthorizationFilter> filterMock = new Mock<IAuthorizationFilter>();
@@ -727,4 +771,21 @@ public bool AllowMultiple
}
}
}
+
+ public class SpyDisposeController : System.Web.Http.ApiController
+ {
+ public static bool DisposeWasCalled = false;
+
+ public SpyDisposeController()
+ {
+ }
+
+ public void Get() { }
+
+ protected override void Dispose(bool disposing)
+ {
+ DisposeWasCalled = true;
+ base.Dispose(disposing);
+ }
+ }
}
View
33 test/System.Web.Http.Test/Dispatcher/DefaultHttpControllerActivatorTest.cs
@@ -74,39 +74,6 @@ public void Create_UsesControllerFromRequestLevelDependencyScope()
mockScope.Verify();
}
- // Release tests
-
- [Fact]
- public void Release_GuardClauses()
- {
- // Arrange
- var controller = new SimpleController();
- var config = new HttpConfiguration();
- var context = new HttpControllerContext();
- var activator = new DefaultHttpControllerActivator();
-
- // Act & assert
- Assert.ThrowsArgumentNull(() => activator.Release(controller: null, controllerContext: context), "controller");
- Assert.ThrowsArgumentNull(() => activator.Release(controller, controllerContext: null), "controllerContext");
- }
-
- [Fact]
- public void Release_CallsDisposeOnController()
- {
- // Arrange
- var mockController = new Mock<IHttpController>();
- var mockDisposable = mockController.As<IDisposable>();
- var config = new HttpConfiguration();
- var context = new HttpControllerContext();
- var activator = new DefaultHttpControllerActivator();
-
- // Act
- activator.Release(mockController.Object, context);
-
- // Assert
- mockDisposable.Verify(d => d.Dispose());
- }
-
// Helper classes
abstract class AbstractController : ApiController { }
View
48 test/System.Web.Http.Test/Tracing/Tracers/HttpControllerDescriptorTracerTest.cs
@@ -59,54 +59,6 @@ public void CreateController_Throws_And_Traces_When_Inner_Throws()
Assert.Same(_exception, traceWriter.Traces[1].Exception);
}
- [Fact]
- public void ReleaseController_Invokes_Inner_And_Traces()
- {
- // Arrange
- Mock<HttpControllerDescriptor> mockControllerDescriptor = CreateMockControllerDescriptor();
- mockControllerDescriptor.Setup(b => b.ReleaseController(It.IsAny<IHttpController>(), It.IsAny<HttpControllerContext>())).Verifiable();
- TestTraceWriter traceWriter = new TestTraceWriter();
- HttpControllerDescriptorTracer tracer = GetHttpControllerDescriptorTracer(mockControllerDescriptor.Object, traceWriter);
-
- TraceRecord[] expectedTraces = new TraceRecord[]
- {
- new TraceRecord(_controllerContext.Request, TraceCategories.ControllersCategory, TraceLevel.Info) { Kind = TraceKind.Begin, Operation = "ReleaseController" },
- new TraceRecord(_controllerContext.Request, TraceCategories.ControllersCategory, TraceLevel.Info) { Kind = TraceKind.End, Operation = "ReleaseController" }
- };
-
- // Act
- tracer.ReleaseController(_controller, _controllerContext);
-
- // Assert
- mockControllerDescriptor.Verify();
- Assert.Equal<TraceRecord>(expectedTraces, traceWriter.Traces, new TraceRecordComparer());
- }
-
- [Fact]
- public void ReleaseController_Throws_And_Traces_When_Inner_Throws()
- {
- // Arrange
- Mock<HttpControllerDescriptor> mockControllerDescriptor = CreateMockControllerDescriptor();
- mockControllerDescriptor.Setup(b => b.ReleaseController(It.IsAny<IHttpController>(), It.IsAny<HttpControllerContext>())).Throws(_exception).Verifiable();
- TestTraceWriter traceWriter = new TestTraceWriter();
- HttpControllerDescriptorTracer tracer = GetHttpControllerDescriptorTracer(mockControllerDescriptor.Object, traceWriter);
-
- TraceRecord[] expectedTraces = new TraceRecord[]
- {
- new TraceRecord(_controllerContext.Request, TraceCategories.ControllersCategory, TraceLevel.Info) { Kind = TraceKind.Begin, Operation = "ReleaseController" },
- new TraceRecord(_controllerContext.Request, TraceCategories.ControllersCategory, TraceLevel.Error) { Kind = TraceKind.End, Operation = "ReleaseController" }
- };
-
- // Act
- Exception thrown = Assert.Throws<InvalidOperationException>(() => tracer.ReleaseController(_controller, _controllerContext));
-
- // Assert
- mockControllerDescriptor.Verify();
- Assert.Equal<TraceRecord>(expectedTraces, traceWriter.Traces, new TraceRecordComparer());
- Assert.Same(_exception, thrown);
- Assert.Same(_exception, traceWriter.Traces[1].Exception);
- }
-
private static HttpControllerDescriptorTracer GetHttpControllerDescriptorTracer(HttpControllerDescriptor controllerDescriptor, ITraceWriter traceWriter)
{
return new HttpControllerDescriptorTracer(
View
84 test/System.Web.Http.Test/Tracing/Tracers/HttpControllerTracerTest.cs
@@ -6,6 +6,8 @@
using Moq;
using Xunit;
using Assert = Microsoft.TestCommon.AssertEx;
+using System.Web.Http.Hosting;
+using System.Collections.Generic;
namespace System.Web.Http.Tracing.Tracers
{
@@ -24,6 +26,71 @@ public HttpControllerTracerTest()
}
[Fact]
+ public void Dispose_TracesAndInvokesInnerDisposeWhenControllerIsDisposable()
+ {
+ // Arrange
+ var mockController = new Mock<IHttpController>();
+ var mockDisposable = mockController.As<IDisposable>();
+ var request = new HttpRequestMessage();
+ var traceWriter = new TestTraceWriter();
+ var tracer = new HttpControllerTracer(request, mockController.Object, traceWriter);
+ var expectedTraces = new[]
+ {
+ new TraceRecord(request, TraceCategories.ControllersCategory, TraceLevel.Info) { Kind = TraceKind.Begin, Operation = "Dispose" },
+ new TraceRecord(request, TraceCategories.ControllersCategory, TraceLevel.Info) { Kind = TraceKind.End, Operation = "Dispose" }
+ };
+
+ // Act
+ ((IDisposable)tracer).Dispose();
+
+ // Assert
+ Assert.Equal(expectedTraces, traceWriter.Traces, new TraceRecordComparer());
+ mockDisposable.Verify(d => d.Dispose(), Times.Once());
+ }
+
+ [Fact]
+ public void Dispose_DoesNotTraceWhenControllerIsNotDisposable()
+ {
+ // Arrange
+ var mockController = new Mock<IHttpController>();
+ var request = new HttpRequestMessage();
+ var traceWriter = new TestTraceWriter();
+ var tracer = new HttpControllerTracer(request, mockController.Object, traceWriter);
+
+ // Act
+ ((IDisposable)tracer).Dispose();
+
+ // Assert
+ Assert.Empty(traceWriter.Traces);
+ }
+
+ [Fact]
+ public void ExecuteAsync_RemovesInnerControllerFromReleaseListAndAddsItselfInstead()
+ {
+ // Arrange
+ var request = new HttpRequestMessage();
+ var context = ContextUtil.CreateControllerContext(request: request);
+ var mockController = new Mock<IHttpController>();
+ var mockDisposable = mockController.As<IDisposable>();
+ mockController.Setup(c => c.ExecuteAsync(context, CancellationToken.None))
+ .Callback<HttpControllerContext, CancellationToken>((cc, ct) => cc.Request.RegisterForDispose(mockDisposable.Object))
+ .Returns(() => TaskHelpers.FromResult(new HttpResponseMessage()))
+ .Verifiable();
+ context.ControllerDescriptor = _controllerDescriptor;
+ context.Controller = mockController.Object;
+ var traceWriter = new TestTraceWriter();
+ var tracer = new HttpControllerTracer(request, mockController.Object, traceWriter);
+
+ // Act
+ ((IHttpController)tracer).ExecuteAsync(context, CancellationToken.None).WaitUntilCompleted();
+
+ // Assert
+ IEnumerable<IDisposable> disposables = (IEnumerable<IDisposable>)request.Properties[HttpPropertyKeys.DisposableRequestResourcesKey];
+ Assert.Contains(tracer, disposables);
+ Assert.DoesNotContain(mockDisposable.Object, disposables);
+ }
+
+ [Fact]
public void ExecuteAsync_Invokes_Inner_And_Traces()
{
// Arrange
@@ -31,14 +98,15 @@ public void ExecuteAsync_Invokes_Inner_And_Traces()
Mock<ApiController> mockController = new Mock<ApiController>() { CallBase = true };
mockController.Setup(b => b.ExecuteAsync(It.IsAny<HttpControllerContext>(), It.IsAny<CancellationToken>())).Returns(TaskHelpers.FromResult<HttpResponseMessage>(response));
- HttpControllerContext controllerContext = ContextUtil.CreateControllerContext(request: new HttpRequestMessage());
+ HttpRequestMessage request = new HttpRequestMessage();
+ HttpControllerContext controllerContext = ContextUtil.CreateControllerContext(request: request);
controllerContext.ControllerDescriptor = _controllerDescriptor;
controllerContext.Controller = mockController.Object;
HttpActionContext actionContext = ContextUtil.CreateActionContext(controllerContext, actionDescriptor: _mockActionDescriptor.Object);
TestTraceWriter traceWriter = new TestTraceWriter();
- HttpControllerTracer tracer = new HttpControllerTracer(mockController.Object, traceWriter);
+ HttpControllerTracer tracer = new HttpControllerTracer(request, mockController.Object, traceWriter);
TraceRecord[] expectedTraces = new TraceRecord[]
{
@@ -64,14 +132,15 @@ public void ExecuteAsync_Faults_And_Traces_When_Inner_Faults()
Mock<ApiController> mockController = new Mock<ApiController>() { CallBase = true };
mockController.Setup(b => b.ExecuteAsync(It.IsAny<HttpControllerContext>(), It.IsAny<CancellationToken>())).Returns(tcs.Task);
- HttpControllerContext controllerContext = ContextUtil.CreateControllerContext(request: new HttpRequestMessage());
+ HttpRequestMessage request = new HttpRequestMessage();
+ HttpControllerContext controllerContext = ContextUtil.CreateControllerContext(request: request);
controllerContext.ControllerDescriptor = _controllerDescriptor;
controllerContext.Controller = mockController.Object;
HttpActionContext actionContext = ContextUtil.CreateActionContext(controllerContext, actionDescriptor: _mockActionDescriptor.Object);
TestTraceWriter traceWriter = new TestTraceWriter();
- HttpControllerTracer tracer = new HttpControllerTracer(mockController.Object, traceWriter);
+ HttpControllerTracer tracer = new HttpControllerTracer(request, mockController.Object, traceWriter);
TraceRecord[] expectedTraces = new TraceRecord[]
{
@@ -95,14 +164,15 @@ public void ExecuteAsync_IsCancelled_And_Traces_When_Inner_IsCancelled()
Mock<ApiController> mockController = new Mock<ApiController>() { CallBase = true };
mockController.Setup(b => b.ExecuteAsync(It.IsAny<HttpControllerContext>(), It.IsAny<CancellationToken>())).Returns(TaskHelpers.Canceled<HttpResponseMessage>());
- HttpControllerContext controllerContext = ContextUtil.CreateControllerContext(request: new HttpRequestMessage());
+ HttpRequestMessage request = new HttpRequestMessage();
+ HttpControllerContext controllerContext = ContextUtil.CreateControllerContext(request: request);
controllerContext.ControllerDescriptor = _controllerDescriptor;
controllerContext.Controller = mockController.Object;
HttpActionContext actionContext = ContextUtil.CreateActionContext(controllerContext, actionDescriptor: _mockActionDescriptor.Object);
TestTraceWriter traceWriter = new TestTraceWriter();
- HttpControllerTracer tracer = new HttpControllerTracer(mockController.Object, traceWriter);
+ HttpControllerTracer tracer = new HttpControllerTracer(request, mockController.Object, traceWriter);
TraceRecord[] expectedTraces = new TraceRecord[]
{
@@ -111,7 +181,7 @@ public void ExecuteAsync_IsCancelled_And_Traces_When_Inner_IsCancelled()
};
// Act
- Task task = ((IHttpController) tracer).ExecuteAsync(controllerContext,CancellationToken.None);
+ Task task = ((IHttpController)tracer).ExecuteAsync(controllerContext, CancellationToken.None);
Exception thrown = Assert.Throws<TaskCanceledException>(() => task.Wait());
// Assert
Please sign in to comment.
Something went wrong with that request. Please try again.