【问题标题】:How to Inject IHostingEnvironment in My Own Class如何在我自己的类中注入 IHostingEnvironment
【发布时间】:2018-12-15 16:10:25
【问题描述】:

我有下面的代码来创建一个日志文件。

public class LoggingService
{
    private readonly IHostingEnvironment env;

    public LoggingService(IHostingEnvironment env)
    {
            this.env = env;
    }

    public void WriteLog(string strLog)
    {
            //Some code is Here
    }
}

在控制器函数中访问类

LoggingService log =  new LoggingService();
log.WriteLog("Inside GetUserbyCredential function");

当我尝试从控制器类创建实例以将某些值传递给函数时。当时我收到以下错误

没有给出与“LoggingService.LoggingService(IHostingEnvironment)”的所需形式参数“env”相对应的参数

如何为此创建实例。

【问题讨论】:

  • 您如何使用LoggingService 类?您能否添加使用 LoggingService 的代码,即创建/注入到控制器中,以及您的 startup.cs(尤其是在您注册 LoggingService 类的地方)。
  • 我没有在 startup.cs 中做任何事情

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


【解决方案1】:

问题出在下面一行:

LoggingService log =  new LoggingService();

当您创建 LoggingService 类的实例时,您没有将 IHostingEnvironment 传递给它的构造函数,这就是它变为 null 的原因。

要解决此问题,请尝试以下操作:

public interface ILoggingService
{
   void WriteLog(string strLog);
}

public class LoggingService : ILoggingService
{

    private readonly IHostingEnvironment env;

    public LoggingService(IHostingEnvironment env)
    {
        this.env = env;
    }
    public void WriteLog(string strLog)
    {

        //Some code is Here
    }
}

然后在你的控制器中:

public class YourController : Controller
{
     private readonly ILoggingService _loggingService;
     public YourController(ILoggingService loggingService)
     {
         _loggingService = loggingService;
     }

     public IActionResult YourMethod()
     {
        _loggingService.WriteLog("Inside GetUserbyCredential function");
     }
}

最后在Startup类的ConfigureServices方法中如下:

public void ConfigureServices(IServiceCollection services)
{
    services.AddScoped<ILoggingService, LoggingService>();
}

【讨论】:

  • 我在启动类中遇到此错误。当前上下文中不存在名称“env”
  • 好的!再次尝试删除 services.AddSingleton&lt;IHostingEnvironment&gt;(env); 并告诉我它是否有效!
  • 您不需要创建接口。您可以直接注册课程。此外,.NET Core 为您注册 IHostingEnvironment,因此不需要代码
  • @SATHEESHP 很高兴看看是否对您有用!欢迎!
  • @SimplyGed 您的方法可能有效,但在您创建服务并通过接口访问服务时,使用接口始终是最佳选择。
【解决方案2】:

.NET Core 中的 DependencyInjection 要求您注册类及其依赖项,以便它可以在创建类的实例之前创建/检索任何依赖项。

根据您的 cmets,我假设您尚未在服务集合中注册您的 LoggingService,并且您正在尝试在控制器中创建一个实例。

首先,您需要在 startup.cs 中使用 IServiceCollection 注册您的 LoggingService

public void ConfigureServices(IServiceCollection services)
{
    services.AddSingleton<LoggingService>();

    services.AddMvc();
}

这告诉 DI 服务,当一个类在其构造函数中请求 LoggingService 时,它必须创建该类的一个实例。在幕后.NET Core 已经将IHostingEnvironment 接口注册到DI 服务,所以我们不必担心。当 DI 服务必须创建 LoggingService 的实例时,它会自动注入 IHostingEnvironment 依赖项。

现在我们需要将类注入到我们的控制器中:

public class ValuesController : Controller
{
    private readonly LoggingService _loggingService;

    public ValuesController(LoggingService loggingService)
    {
        _loggingService = loggingService;
    }

    ...
}

.NET Core 创建ValuesController 的实例时,它会查看它是否知道如何创建LoggingService 的实例 - 这是因为我们在startup.cs 中告诉它我们的类。

关于依赖注入要记住的一点是,您几乎总是从不使用new 创建一个类。 (这也有例外,但您应该始终尝试让 DI 服务创建类,而无需使用 new 关键字)。

我建议您花一些时间阅读documentation on Dependency Injection,以便您完全了解依赖注入在ASP.NET Core 中的工作原理以及可用的不同范围。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-10-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多