I'm using .NET 7 Preview with ASP.NET to wrap a bunch of WCF services so they're REST. Each service has its own controller and I'm using dependency injection with the constructor.
Each WCF service is automatically generated with its own client and a couple methods that I use delegates on the base class (MyBaseController
) to handle all the logic and things.
The problem is I need the injected dependencies, but if I change the base constructor, I have to modify 40+ derived classes.
Below is the basic concept I'm using, but ideally the derived classes would only contain delegate overrides and the class definition providing the generics.
You can see for derived classes A
/B
, I have to have a constructor.
Questions:
Is there another method of dependency injection where I don't have to declare them in the constructor? This would allow me to handle it in the base class and then keep a simple constructor in the derived classes.
Can I inherit the base constructor somehow? - I don't think there is with older versions of .NET so I was hoping .NET 7 might have some new magic I didn't know about.
Should I be moving all of my constructor needs into a service class and then just passing that everywhere to the controllers?
Code:
[ApiController]
[Route("[controller]")]
public abstract class MyBaseController<DerivedClient, MyRequest, MyResponse> : ControllerBase
where DerivedClient : HttpClient, new()
{
protected DerivedClient _derivedClient;
protected readonly ILogger _logger;
public IConfiguration _configuration;
protected IOptions<MyOptions> _options;
public abstract Func<MyRequest, Task<MyResponse>> MyClientDelegate { get; }
protected MyBaseController(ILogger<DerivedClient> logger, IOptions<MyOptions> options, IConfiguration configuration)
{
// I need these dependencies though, and with a simple constructor (i.e. MyBaseController()),
// I can't access them.
_derivedClient = new();
_logger = logger;
_options = options;
_configuration = configuration;
}
[HttpGet, Route("GetTheData")]
public Task<MyResponse> GetTheData(MyRequest request)
{
return MyClientDelegate(request);
}
}
public class A : MyBaseController<AClient, string, string>
{
// How can I avoid having this in every derived class when they're all essentially identical?
public A(ILogger<AClient> logger, IOptions<MyOptions> options, IConfiguration configuration) : base(logger, options, configuration) { }
// I only want my derived classes to have the delegate
public override Func<string, Task<string>> MyClientDelegate => _derivedClient.GetDataA;
}
public class B : MyBaseController<BClient, string, string>
{
// How can I avoid having this in every derived class when they're all essentially identical?
public B(ILogger<BClient> logger, IOptions<MyOptions> options, IConfiguration configuration) : base(logger, options, configuration){ }
// I only want my derived classes to have the delegate
public override Func<string, Task<string>> MyClientDelegate => _derivedClient.GetDataB;
}
public class AClient : HttpClient
{
public AClient() { }
public Task<string> GetDataA(string request)
{
return Task.FromResult($"A Request: {request}");
}
}
public class BClient : HttpClient
{
public BClient() { }
public Task<string> GetDataB(string request)
{
return Task.FromResult($"B Request: {request}");
}
}