Получить Сервис и использовать его в каком-то произвольном классе в сетевом ядре

Есть множество примеров, как настроить контроллеры на использование сервисов и т. Д. Но как насчет простого старого класса? Позволяет использовать простой сервис настройки

JSON

{
  ....,
  "AppSettings": {
    "SchemaFile": "some file name.xml"
  }  
}

ПОКО

public class AppSettings
{
    public string SchemaFile { get;set; }
}

В автозагрузке

public void ConfigureServices(IServiceCollection services)
{
    IConfigurationSection appSettingsSection = Configuration.GetSection("AppSettings");
    services.Configure<AppSettings>(appSettingsSection);
  . . . . 
}

Это точка, где все примеры перемещаются непосредственно к контроллеру. Но у нас будет много кода вне контроллера. Что мне нужно, чтобы получить доступ к этой услуге с помощью provider.GetService(typeof(T)) или же provider.GetRequiredService(typeof(T)), скажем, статический класс

internal static MyClass
{
    internal static void DosomeThing()
    {
        // acquire my service
        // use it to retrieve some value
        // continue with my logic

    }
}

Спасибо

2 ответа

Так же, как сервисы могут быть внедрены в контроллеры, так и они могут быть внедрены в другие классы.

статические классы, однако, не подходят для внедрения зависимостей по умолчанию.

Вместо того чтобы использовать статический класс, создайте обычный класс и явно зависите от желаемого сервиса посредством внедрения конструктора

internal class MyClass : IMyService {
    readonly AppSettings settings;

    public MyClass(AppSettings settings) {
        this.settings = settings;
    }

    internal void DosomeThing() {
        // retrieve some value from settings
        // continue with my logic
    }
}

Затем вы можете зарегистрировать желаемое POCO и утилиты в сервисном контейнере.

public void ConfigureServices(IServiceCollection services) {
    AppSettings appSettings = Configuration.GetSection("AppSettings").Get<AppSettings>();
    services.AddSingleton(appSettings);
    services.AddSingleton<IMyService, MyClass>();
    //. . . . 
}

Внедрите свой сервис там, где это необходимо, и он будет иметь доступ к POCO при разрешении на инъекцию.

Там действительно не нужно проходить IServiceProvider вокруг, что можно рассматривать как запах кода.

Упрощение вашего проекта в соответствии с принципом явной зависимости должно сделать ваш код более НАДЕЖНЫМ, а также более простым для сопровождения и сопровождения.

Вы должны пройти AppSettings как параметр из метода вызывающего

public class HomeController : Controller
{
   public HomeController(AppSettings settings)
   {
      this.Settings = settings;
   }

   private AppSettings Settings { get; }

   public IActionResult Index()
   {
      MyClass.DosomeThing(this.Settings);
   }
}

internal static MyClass
{
    internal static void DosomeThing(AppSettings settings)
    {
        // acquire my service
        // use it to retrieve some value
        // continue with my logic

    }
}
Другие вопросы по тегам