Quantcast
Channel: Recent Questions - Stack Overflow
Viewing all articles
Browse latest Browse all 11691

How to use a primary constructor with dependency injection?

$
0
0

I have been reading the introductory guide for primary constructors in c#12 and I'm getting some unexpected results (https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/tutorials/primary-constructors).

I have some code like:

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

Now, if I create a unit test like this:

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

In the call to _sut.Method();, inside, the service that is provided in the test via a mock, it's actually null in ServiceA.Method. The mock is correctly created in the unit test, but it doesn't make it to the method.

A way I found to solve this is by creating a property or field to capture the Primary constructor parameter and then use that instead of the parameter. Something like this:

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    }}

As I said, the above now works, however from what I understand from the docs, that parameter capturing should not be necessary: https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/tutorials/primary-constructors#dependency-injection

Another common use for primary constructors is to specify parameters for dependency injection. The following code creates a simple controller that requires a service interface for its use:C#

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

The primary constructor clearly indicates the parameters needed in the class. You use the primary constructor parameters as you would any other variable in the class.

-> Am I misunderstanding Primary constructors?


Viewing all articles
Browse latest Browse all 11691

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>