Search code examples
asp.net-coremiddleware

Inject route data using middleware


I'm building a very simple rest api. All my endpoints under a specific controller requires an object of type QueryContext. This object is a "simplified" version of HttpRequest.

Currently, I use a factory accepting an HttpRequest and returning a object of type QueryContext.

public interface IQueryContextFactory
{
    QueryContext Create(string query, HttpRequest request);
}

internal class HttpRequestQueryContextFactory : IQueryContextFactory
{
    public QueryContext Create(string query, HttpRequest request)
    {
        if (string.IsNullOrEmpty(query))
            throw new ArgumentNullException(nameof(query));
        if (request == null)
            throw new ArgumentNullException(nameof(request));

        return new QueryContext
        {
            Method = request.Method,
            QueryString = string.Concat(query, request.QueryString),
            Parameters = request.Query.ToDictionary(x => x.Key, x => x.Value.ToString().Replace("\"", string.Empty)),
            Headers = request.Headers.ToDictionary(x => x.Key, x => x.Value.ToString())
        };
    }
}

Then i call this factory from my endpoint

    [HttpGet]
    public IActionResult Process(string query)
    {
        (...)
        var ctx = _contextFactory.Create(query, Request);
    }

Is this recommended to use a middleware to add the QueryContext to the route data? This i would be able to get it as a parameter?


Solution

  • You can inject a IQueryContextFactory in your API Controller.

    Here's an example:

    [Route("api/my")]
    public class MyController : Controller {
    
        private readonly IQueryContextFactory QueryContextFactory;
    
        public MyController(IQueryContextFactory queryContextFactory) {
          if (queryContextFactory == null)
            throw new ArgumentNullException(nameof(queryContextFactory));
          QueryContextFactory = queryContextFactory;
        }
    
        [HttpGet]
        public IActionResult Get(string query) {
          var ctx = QueryContextFactory.Create(query, Request);
          return Ok();
        }
    }
    

    Then, you configure the injection in your Startup.cs like this:

    public void ConfigureServices(IServiceCollection services) {
      //...
      services.AddSingleton<IQueryContextFactory, HttpRequestQueryContextFactory>();
      //...
    }
    

    You can find more info about injection here.