gpt4 book ai didi

c# - 在依赖注入(inject)中检查 null 的更好方法

转载 作者:太空狗 更新时间:2023-10-30 00:01:24 26 4
gpt4 key购买 nike

当通过构造函数使用依赖注入(inject)时,我总是需要在将实例传递给内部属性之前检查空值。例如

public UserManager(User user, IStateManager stateManager)
{
if(user == null) throw new ArgumentNullException;
if(statemanager == null) throw new ArgumentNullException("stateManager");

_user = user;
_stateManager = statemanager;
}

在每个 Controller /类上重复此模式似乎是重复的。有没有更好的方法来处理这个问题?顺便说一句,不同的 Controller 将有不同的构造函数初始化器。我正在为我的 DI 使用 Simple Injector。

最佳答案

这是重复的代码,但它几乎不会成为问题,因为这会导致您的代码库发生彻底更改吗?您是否需要更改其中许多支票?几乎不。看看this blog post对此有更多详细信息。

老实说,说到我的injection constructors ,我几乎不再添加那些空检查,因为我知道我的 DI 容器在自动连接这些类型时不会将空引用注入(inject)我的构造函数。这使我完全不用编写所有这些空检查。

有些人可能会争辩说我现在在编写代码时考虑了我的 DI 容器,但我反对这种说法。我只是在编写解决我的问题所需的最少代码。添加这些空检查对我的情况没有帮助。

但请注意,如果我正在为可重用库编写代码,我绝对会编写那些空检查,因为我不知道谁在调用该代码。对于不用作注入(inject)构造函数(消息、实体、值类型、DTO)的构造函数,我实际上确实添加了这些检查。但是这里有一些想法可以使它变得更好:

你可以像这样添加一个很好的辅助方法:

public UserManager(User user, IStateManager stateManager)
{
Requires.IsNotNull(user, "user");
Requires.IsNotNull(statemanager, "statemanager");

_user = user;
_stateManager = statemanager;
}

然而,这并不能真正帮助减少重复代码,尽管它确实减少了生成的机器代码的实际大小(但这几乎不是问题)。因此,您可以使此方法返回如下值:

public UserManager(User user, IStateManager stateManager)
{
_user = Requires.IsNotNull(user, "user");
_stateManager = Requires.IsNotNull(statemanager, "statemanager");
}

或者...使用 C# 6.0:

public UserManager(User user, IStateManager stateManager)
{
_user = Requires.IsNotNull(user, nameof(user));
_stateManager = Requires.IsNotNull(statemanager, nameof(statemanager));
}

您可以按如下方式实现此方法:

public static class Requires {
public static T IsNotNull<T>(T instance, string paramName) where T : class {
// Use ReferenceEquals in case T overrides equals.
if (object.ReferenceEquals(null, instance)) {
// Call a method that throws instead of throwing directly. This allows
// this IsNotNull method to be inlined.
ThrowArgumentNullException(paramName);
}

return instance;
}

private static void ThrowArgumentNullException(paramName) {
throw new ArgumentNullException(paramName);
}
}

使用 C# 8 non-nullable reference types ,默认情况下可以使引用类型不可为空:

public UserManager(User user, IStateManager stateManager)
{
_user = user;
_stateManager = statemanager;
}

请注意,这只会导致编译时强制执行,而不是运行时强制执行。所以不会抛出异常。

这可能会随着 C# 9 的变化而改变。有人提议使用 ! 符号添加运行时检查:

public UserManager(User user!, IStateManager stateManager!)
{
_user = user;
_stateManager = statemanager;
}

关于c# - 在依赖注入(inject)中检查 null 的更好方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26334478/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com