Quantcast
Channel: ASP.NET Core
Viewing all articles
Browse latest Browse all 9386

MVC6 Middleware - Constructor fires only one time?

$
0
0

By following samples I wrote a simple middleware to log some request details. I am not sure why Middleware constructor which takes RequestDelegate doesn't fire with each request. I simply added a breakpoint on Middleware constructor and fired multiple request one by one from browser, I can see Middleware constructor getting fired only first time. On subsequent call it doesn't call constructor. Is this correct? Why?

Also, does it mean that If I have a scoped service (generating GUID) and if middleware constructor is taking this scoped service as one of the parameter, my GUID will be the same for all request? Should I not pass scoped service as constructor parameter?

My middleware is as follows: As you can see I am passing IRequestIdService as constructor parameter and all request have same guid.

public class RequestLoggerMiddleware
    {
        private readonly RequestDelegate _next;
        private readonly IUserProfileService _userProfileService;
        private readonly IRequestIdService _requestIdService;
        private readonly ILogger<RequestLoggerMiddleware> _logger;

        public RequestLoggerMiddleware(RequestDelegate next,
                                       IUserProfileService userProfileService,
                                       IRequestIdService requestIdService,
                                       ILogger<RequestLoggerMiddleware> logger)
        {
            _next = next;
            _userProfileService = userProfileService;
            _requestIdService = requestIdService;
            _logger = logger;
        }

        public async Task Invoke(HttpContext context)
        {
            var auditSummary = new AuditSummary
            {
                AuditId = _requestIdService.RequestId,
                GPID = _userProfileService.GPID,
                Method = context.Request.Method,
                Path = context.Request.Path,
            };

            _logger.LogInformation($"{auditSummary.AuditId} - {auditSummary.GPID} - {auditSummary.Method} - {auditSummary.Path}");

            await _next.Invoke(context);
        }
    }

If I change my code to look as follows then it works fine. Which means I shouldn't pass UserProfileService in constructor too.

public class RequestLoggerMiddleware
    {
        private readonly RequestDelegate _next;
        private readonly IUserProfileService _userProfileService;
        private IRequestIdService _requestIdService;
        private readonly ILogger<RequestLoggerMiddleware> _logger;

        public RequestLoggerMiddleware(RequestDelegate next,
                                       IUserProfileService userProfileService,
                                       ILogger<RequestLoggerMiddleware> logger)
        {
            _next = next;
            _userProfileService = userProfileService;
            _logger = logger;
        }

        public async Task Invoke(HttpContext context)
        {
            _requestIdService = context.RequestServices.GetRequiredService<RequestIdService>();

            var auditSummary = new AuditSummary
            {
                AuditId = _requestIdService.RequestId,
                GPID = _userProfileService.GPID,
                Method = context.Request.Method,
                Path = context.Request.Path,
            };

            _logger.LogInformation($"{auditSummary.AuditId} - {auditSummary.GPID} - {auditSummary.Method} - {auditSummary.Path}");

            await _next.Invoke(context);
        }
    }

Towards the end of the article (http://dotnetliberty.com/index.php/2015/12/28/asp-net-5-scoped-dependencies/) author describes "Singleton Captures Scoped". That is what I am facing. 

Anyone can explain?


Viewing all articles
Browse latest Browse all 9386

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>