如何通过依赖注入使用主构造函数?

Gon*_*nan 8 .net c#

我一直在阅读 c#12 中主要构造函数的介绍指南,并且得到了一些意想不到的结果(https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/tutorials/primary-constructors)。

我有一些代码,例如:

public class ServiceA(IServiceB service)
{
    public async Task<bool> Method() {
        return await service.GetValue();
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,如果我创建一个像这样的单元测试:

[Fact]
public void Test1() {
    var mockB = Substitute.For<IServiceB>();
    _sut = new SeviceA(mockB);
    _sut.Method();
    Assert.NotNull(mockB);
}
Run Code Online (Sandbox Code Playgroud)

在对测试_sut.Method();service通过模拟提供的 的调用中,它实际上null位于 ServiceA.Method 中。模拟在单元测试中正确创建,但它没有进入方法。

我发现解决此问题的一种方法是创建一个属性或字段来捕获主构造函数参数,然后使用它而不是参数。像这样的东西:

public class ServiceA(IServiceB service)
{
    private IServiceB ServiceProperty { get; } = service; //capture the parameter
    public async Task<bool> Method() {
        return await ServiceProperty.GetValue(); //use property instead of parameter
    }
}
Run Code Online (Sandbox Code Playgroud)

正如我所说,上面的内容现在可以工作,但是根据我从文档中了解到的内容,参数捕获应该不是必需的:https ://learn.microsoft.com/en-us/dotnet/csharp/whats-new/tutorials/主构造函数#依赖注入

主构造函数的另一个常见用途是指定依赖项注入的参数。以下代码创建一个简单的控制器,需要一个服务接口才能使用:C#

 public interface IService
 {
     Distance GetDistance();
 }
 public class ExampleController(IService service) : ControllerBase
 {
     [HttpGet]
     public ActionResult<Distance> Get()
     {
         return service.GetDistance();
     }
}
Run Code Online (Sandbox Code Playgroud)

主构造函数清楚地表明了类中所需的参数。您可以像使用类中的任何其他变量一样使用主构造函数参数。

-> 我是否误解了主构造函数?

小智 0

我不确定这是否能解决每个人的问题,但它为我解决了问题。

问题实际上是我需要更多的主要构造函数。

一些注入的服务没有主构造函数,因此我测试了将构造函数添加到我的服务实现中,之后它开始按预期工作。

我仍然认为没有它应该可以工作,但现在即使没有捕获参数它也可以工作。

希望这对某人有帮助!

编辑:仅供参考,参数在调试器中仍然显示为 null,但由于某种原因它们在运行时工作。