.NET Core中如何在控制器中为新建类对象提供ILogger<ClassName>实例以解决空引用错误
解决.NET Core中自定义类正确获取ILogger实例的问题
你的问题核心在于手动实例化自定义类时没有利用.NET Core的依赖注入(DI)容器来提供ILogger实例,导致传入null引发错误,或者Logger无法正常工作。下面给你几种可行的解决方案:
方案1:在控制器中注入ILogger并传递给自定义类
因为控制器本身是由DI容器管理的,你可以直接把ILogger<MyModel>注入到控制器的构造函数中,再用这个实例来初始化MyModel:
public class MyController : Controller { private readonly ILogger<MyController> _controllerLogger; private readonly ILogger<MyModel> _modelLogger; // 注入控制器自身和MyModel的Logger实例 public MyController(ILogger<MyController> controllerLogger, ILogger<MyModel> modelLogger) { _controllerLogger = controllerLogger; _controllerLogger.LogInformation("Log Testing"); _modelLogger = modelLogger; } public ActionResult List() { int Id = 5; // 使用注入的Logger实例初始化MyModel,避免传入null MyModel model = new MyModel(_modelLogger); model.GetItem(Id); return View("List", model); } }
这样MyModel的_logger就会被正确赋值,catch块中的日志代码也能正常执行。
方案2:将MyModel注册到DI容器(推荐)
更符合.NET Core设计理念的做法是把MyModel也纳入DI管理,让容器自动处理它的依赖注入,包括ILogger<MyModel>:
第一步:注册MyModel到DI容器
在你的Program.cs(.NET 6+)或者Startup.cs(.NET 5及更早版本)中,添加以下代码:
// .NET 6+ Program.cs builder.Services.AddScoped<MyModel>(); // 可选:根据你的业务需求选择生命周期:AddTransient(每次请求创建新实例)、AddSingleton(全局单例)
第二步:在控制器中直接注入MyModel
修改控制器的构造函数,直接注入MyModel,容器会自动把ILogger<MyModel>注入到MyModel的构造函数中:
public class MyController : Controller { private readonly ILogger<MyController> _logger; private readonly MyModel _myModel; public MyController(ILogger<MyController> logger, MyModel myModel) { _logger = logger; _logger.LogInformation("Log Testing"); _myModel = myModel; } public ActionResult List() { int Id = 5; _myModel.GetItem(Id); return View("List", _myModel); } }
这种方式完全避免了手动实例化,让DI容器统一管理依赖,减少代码耦合。
临时应急方案:使用NullLogger(不推荐)
如果你只是想临时避免null错误,不想修改DI配置,可以使用NullLogger<MyModel>.Instance传递一个空的Logger实例(但不会输出任何日志):
MyModel model = new MyModel(NullLogger<MyModel>.Instance);
内容的提问来源于stack exchange,提问作者CoderGuy
相关产品推荐
相关产品推荐

