Jos*_*VdM 1 c# dependency-injection constructor-injection null-check .net-core
我正在使用.NET Core构造函数注入。在一位同事的代码审查中,他提出了一个问题,即我是否应该检查控制器中注入的依赖项的空值。
由于该框架负责创建服务的实例,因此在我看来,它将处理所有错误,并且永远不会将空值依赖项传递给构造函数。不过,我没有任何事实证据,因此我想知道是否有必要进行null检查。
例如,是否应该检查以下代码中的“ myService”是否为null?(假设代码配置为使用DI)
public class MyController
{
private readonly IMyService _myService;
public MyController(IMyService myService)
{
_myService = myService;
}
}
Run Code Online (Sandbox Code Playgroud)
为了避免显而易见的问题,在构造函数中进行空检查并没有什么坏处。
有两种方法可以从框架获取 DI 服务。
第一个是GetService<T>()。如果此类服务尚未注册,这将返回空值。
第二个是GetRequiredService<T>()。如果找不到服务,这将引发异常。
如果这两种方法无法完全实例化您所请求的服务,则会抛出异常。
class Program
{
static void Main(string[] args)
{
var services = new ServiceCollection()
.AddTransient<IServiceB, ServiceB>()
.BuildServiceProvider();
var servB = services.GetService<IServiceB>();
}
}
public interface IServiceA { }
public interface IServiceB { }
public class ServiceA : IServiceA { }
public class ServiceB : IServiceB { public ServiceB(IServiceA a) { } }
Run Code Online (Sandbox Code Playgroud)
在此示例中,ServiceB需要IServiceA,但未A添加到依赖关系图中。最后一个方法会抛出异常:
System.InvalidOperationException:“尝试激活“DITests.ServiceB”时无法解析类型“DITests.IServiceA”的服务。”
如果我这样做services.GetService<IServiceA>(),我会得到一个空值。
您可以通过查看GitHub 源代码来亲自了解这一点。当调用任一方法时,它最终都会到达该CreateConstructorCallSite方法。如果无法解析您的类型的依赖关系,则会引发异常。
至于 ASP.Net Core MVC,它用于GetRequiredService<>()从 DI 图中获取控制器。
总之,不,如果您使用纯 Microsoft DI 框架,则无需在构造函数中对 DI 对象执行 null 检查。正如 Camilo Terevinto 所说,框架不允许这样做。
正如您在帖子中所指出的,我还没有看到微软的书面文档明确表示您不需要
如果您将 an 作为构造函数参数传递IServiceProvider,并且要从构造函数内解析服务,则需要执行 null 检查。
是否有必要使用构造函数注入检查空值?
这取决于。
别。这不是必需的。该框架不允许这样做。
然后去做 手动实例化会在某处导致NullReferenceException,并且很难找到它们。
就是说,使用这样的东西:
public MyController(IMyService myService)
{
if (myService == null)
{
throw new ArgumentNullException(nameof(myService));
}
_myService = myService;
}
Run Code Online (Sandbox Code Playgroud)
这是一种非常便宜的支票,如果有人null出于某种原因通过,则更容易追踪。
| 归档时间: |
|
| 查看次数: |
1095 次 |
| 最近记录: |