Hosting 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. commit 5748898fc42b335de05ef2c1b1586babb8039d50
  2. Author: David Fowler <[email protected]>
  3. Date: Wed Mar 21 08:58:03 2018 -0700
  4. Make the RequestServicesContainerMiddleware thinner (#1360) (#1362)
  5. - Today the request services middleware is responsible for making sure there are request scoped services.
  6. This PR tries introduces some breaking changes that are hopefully acceptable in order to gain some performance.
  7. - Here are the assumptions this PR makes:
  8. - Since this middleware is first in the pipeline, the only thing that can
  9. set a default service provider would be the server itself. Since we have no servers that do that
  10. I removed that code that tries to noop if there's an existing service provider.
  11. - This PR no longer restores the previous service provider feature since it gets replaced every request
  12. anyways. Kestrel also clears out the feature on each request so it shouldn't be a problem (in theory).
  13. Once again, since this middleware is first, it is the last thing that runs before the server re-gains
  14. control on the way out so there's no need to restore anything.
  15. - We use the RegisterForDispose method to dispose of the IServiceProvider instead of doing it inline.
  16. diff --git a/src/Microsoft.AspNetCore.Hosting/Internal/RequestServicesContainerMiddleware.cs b/src/Microsoft.AspNetCore.Hosting/Internal/RequestServicesContainerMiddleware.cs
  17. index 8f30c3195c4..22b034ee34c 100644
  18. --- a/src/Microsoft.AspNetCore.Hosting/Internal/RequestServicesContainerMiddleware.cs
  19. +++ b/src/Microsoft.AspNetCore.Hosting/Internal/RequestServicesContainerMiddleware.cs
  20. @@ -30,34 +30,17 @@ namespace Microsoft.AspNetCore.Hosting.Internal
  21. _scopeFactory = scopeFactory;
  22. }
  23. - public async Task Invoke(HttpContext httpContext)
  24. + public Task Invoke(HttpContext httpContext)
  25. {
  26. Debug.Assert(httpContext != null);
  27. // local cache for virtual disptach result
  28. var features = httpContext.Features;
  29. - var existingFeature = features.Get<IServiceProvidersFeature>();
  30. - // All done if RequestServices is set
  31. - if (existingFeature?.RequestServices != null)
  32. - {
  33. - await _next.Invoke(httpContext);
  34. - return;
  35. - }
  36. + var servicesFeature = new RequestServicesFeature(httpContext, _scopeFactory);
  37. - var replacementFeature = new RequestServicesFeature(_scopeFactory);
  38. -
  39. - try
  40. - {
  41. - features.Set<IServiceProvidersFeature>(replacementFeature);
  42. - await _next.Invoke(httpContext);
  43. - }
  44. - finally
  45. - {
  46. - replacementFeature.Dispose();
  47. - // Restore previous feature state
  48. - features.Set(existingFeature);
  49. - }
  50. + features.Set<IServiceProvidersFeature>(servicesFeature);
  51. + return _next.Invoke(httpContext);
  52. }
  53. }
  54. }
  55. \ No newline at end of file
  56. diff --git a/src/Microsoft.AspNetCore.Hosting/Internal/RequestServicesFeature.cs b/src/Microsoft.AspNetCore.Hosting/Internal/RequestServicesFeature.cs
  57. index 8d85cec63ec..a57df9bcbc4 100644
  58. --- a/src/Microsoft.AspNetCore.Hosting/Internal/RequestServicesFeature.cs
  59. +++ b/src/Microsoft.AspNetCore.Hosting/Internal/RequestServicesFeature.cs
  60. @@ -3,6 +3,7 @@
  61. using System;
  62. using System.Diagnostics;
  63. +using Microsoft.AspNetCore.Http;
  64. using Microsoft.AspNetCore.Http.Features;
  65. using Microsoft.Extensions.DependencyInjection;
  66. @@ -14,10 +15,12 @@ namespace Microsoft.AspNetCore.Hosting.Internal
  67. private IServiceProvider _requestServices;
  68. private IServiceScope _scope;
  69. private bool _requestServicesSet;
  70. + private HttpContext _context;
  71. - public RequestServicesFeature(IServiceScopeFactory scopeFactory)
  72. + public RequestServicesFeature(HttpContext context, IServiceScopeFactory scopeFactory)
  73. {
  74. Debug.Assert(scopeFactory != null);
  75. + _context = context;
  76. _scopeFactory = scopeFactory;
  77. }
  78. @@ -27,6 +30,7 @@ namespace Microsoft.AspNetCore.Hosting.Internal
  79. {
  80. if (!_requestServicesSet)
  81. {
  82. + _context.Response.RegisterForDispose(this);
  83. _scope = _scopeFactory.CreateScope();
  84. _requestServices = _scope.ServiceProvider;
  85. _requestServicesSet = true;