2016-12-08 9 views
1

Я строю очень простой отдых api. Все мои конечные точки под определенным контроллером требуют объекта типа QueryContext. Этот объект является «упрощенной» версией HttpRequest.Ввести данные маршрута с помощью промежуточного программного обеспечения

В настоящее время я использую фабрику, принимающую HttpRequest и возвращающую объект типа 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()) 
     }; 
    } 
} 

Тогда я называю этот завод из моей конечной

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

Это рекомендуется использовать промежуточное программное обеспечение, чтобы добавить QueryContext к маршрутизации данных? Это я мог бы получить в качестве параметра?

ответ

0

Вы можете ввести IQueryContextFactory в свой контроллер API.

Вот пример:

[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(); 
    } 
} 

Затем настроить укол в Startup.cs так:

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

Вы можете найти более подробную информацию о инъекции here.

+0

Я подойду к этому подходу, так как легче провести единый тест! – Seb

0

Как вы показали, все данные в вашем упрощенном классе QueryContext также находятся в HttpContext. Вместо того, чтобы вводить в ваш объект другой объект, вы могли бы сделать пару разных вещей.

  1. Инициализировать свойство QueryContext или в поле конструктор вашего контроллера. Таким образом, он доступен всем вашим методам контроллера без дублирования кода.

  2. Скорее добавить новый класс, расширить класс HttpContext с помощью некоторых методов расширения, которые делают то, что вы хотите.

+0

Если вы расширяете HttpContext, это все еще легко для модульного тестирования? – Seb

+0

Ну, действительно легко проверить методы расширения HttpContext, но это, вероятно, не ваш вопрос. Когда дело доходит до модульных контрольных контроллеров, я подозреваю, что ответ отрицательный. В почти всех приложениях, с которыми я работаю в MVC, контекст влияет на контроллеры по-разному, чем описывается в начальном сообщении .... думаю о теге [Authorize]. Фасад вокруг HttpContext не дает общего решения. Я бы тестировал, используя вместо этого Web-версию. Таким образом, я мог полностью подделать HttpContext, включая инъекцию других вещей, таких как DbContext ... – GlennSills