Атрибут фильтра с внедрением зависимостей - PullRequest
0 голосов
/ 16 января 2019

Я пытаюсь полностью понять инъекции зависимости. Я определяю фильтр и хотел бы прочитать из файла конфигурации. Лучше ли создавать экземпляр Configuration внутри фильтра или это можно сделать глобально, например, при запуске? Если да, то какие-нибудь указатели на то, как это сделать?

public class CompanyFilter : ActionFilterAttribute
{
   string _ERPUrl;
   public CompanyFilter(IConfiguration iconfiguration)
   {
       ERPUrl = iconfiguration.GetSection("AppSettings").GetSection("ERPUrl").Value;  

    }
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        if (filterContext.Controller is Controller controller)
            controller.ViewBag.ERPUrl = _ERPUrl;      
            //filterContext.Controller.ViewBag.Company = "Test";
    }
}

Класс запуска

public class Startup
{


    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }
....

Контроллеры

namespace Projects.Controllers
{
    [CompanyFilter]
    public class HomeController : Controller
    {
....

Произошла следующая ошибка.

Controllers \ HomeController.cs (14,6): ошибка CS7036: не указан аргумент, соответствующий необходимому формальному параметру 'iconfiguration' в 'CompanyFilter.CompanyFilter (IConfiguration)'

Ответы [ 3 ]

0 голосов
/ 16 января 2019

Основываясь на некоторых отзывах, можно выполнить следующее, добавив файл Startup.cs.

services.AddMvc(options => {
   options.Filters.Add(new ERPFilter(Configuration));
}

URL может быть учтен в соответствии с приведенным выше пунктом для повышения производительности.

url = ...
services.AddMvc(options => {
   options.Filters.Add(new ERPFilter(url));
}
0 голосов
/ 17 января 2019

Чтобы получить ответ на основе комментариев, предоставленных вчера другими людьми и мной, рекомендуется добавить IOptions<T> в ваши фильтры или любые другие объекты, для которых требуется ввод данных конфигурации.

Вы можете добавить свои настройки ERP в файл appSettings.json следующим образом:

{
  "Logging": {
    "LogLevel": {
      "Default": "Warning"
    }
  },
  "AllowedHosts": "*",
  "Erp": {
    "Url": "https://localhost"
  }
}

Чтобы ввести ваши настройки в зависимости, вы должны зарегистрировать его через ConfigureServices, вы также заметите, что CompanyFilter добавляется к IServiceCollection через AddTransient, это позволяет ServiceFilterAttribute разрешать его на более позднем этапе и внедрить все зависимости, которые есть у фильтра.

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);

    services.Configure<ErpSettings>(Configuration.GetSection("Erp"));
    services.AddTransient<CompanyFilter>();
}

Чтобы применить ваш фильтр к действию контроллера, используйте ServiceFilterAttribute (Type) `

[HttpGet]
[ServiceFilter(typeof(CompanyFilter))]
public ActionResult<IEnumerable<string>> Get()
{
    return new string[] { ViewBag.ERPUrl };
}

В приведенном выше коде вы увидите, что я возвращаю ViewBag.ERPUrl, это потому, что ваш ComapnyFilter переопределил OnActionExecuting, который выполняется до того, как будет вызвано действие, тогда как OnActionExecuted вызывается после того, как ваше действие закончено и до того, как ответ возвращается вызывающему.

Вот как теперь выглядит CompanyFilter, вы заметите, что конструктор теперь принимает IOptions<ErpSettings>

public class CompanyFilter : ActionFilterAttribute
{
    private readonly ErpSettings erpSettings;
    public CompanyFilter(IOptions<ErpSettings> erpSettings)
    {
        this.erpSettings= erpSettings.Value;

    }

    public override void OnActionExecuting(ActionExecutingContext context)
    {
        if (context.Controller is Controller controller)
            controller.ViewBag.ERPUrl = erpSettings.Url;
    }
}

Со всем этим сделано, это ответ

API Response

0 голосов
/ 16 января 2019

Я бы предложил вам использовать IOptions<T> для получения конфигурации из файла со всеми преимуществами, поддерживаемыми .Net Core. Вы можете увидеть, как это сделать здесь .

Кроме того, чтобы добавить его в распознаватель инъекций зависимостей, добавьте services.AddTransient(p => new MyService(mySettings)); к вашей функции ConfigureServices() в качестве переходного процесса, области действия или синглтона (решите, какая из них вам больше подходит).

Если вы настаиваете на использовании IConfiguration для получения конфигурации и решения возникшей проблемы, вам следует внедрить свой экземпляр IConfiguration, например, services.AddSingleton(Configuration);. Надеюсь, что это решит вашу проблему.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...