检索服务并在网络核心的任意类中使用它

时间:2019-05-30 21:19:53

标签: c# .net-core asp.net-core-3.0

有很多示例,如何设置控制器以使用服务等。但是普通的旧类呢?让我们使用一些简单的配置服务

JSON

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

POCO

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

在startup.cs

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 个答案:

答案 0 :(得分:1)

就像可以将服务注入控制器一样,也可以将它们注入其他类。

静态类在默认情况下不适合依赖注入。

创建一个常规类,而不是使用静态类,而是通过构造函数注入显式依赖于所需的服务

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,因为这可以看作是代码味道。

简化设计以遵循显式依赖原则,应使您的代码更扎实,易于遵循和维护。

答案 1 :(得分:0)

您应该通过调用方方法传递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

    }
}