Metalama method aspect not getting injected properties

4 weeks ago 16
ARTICLE AD BOX

I am attempting to implement a version of the Metalama Retry 5 example in our application as a first step to see if Metalama will be beneficial for our uses cases. However, I am running into an issue with the [IntroduceDependency] fields; they don't seem to be getting injected even though DI is setup for them.

For the RetryAttribute I have (this class is in a shared class library as the solution has multiple projects which should be able to use this):

public class RetryAttribute : OverrideMethodAspect { [IntroduceDependency] private readonly ILogger _logger; [IntroduceDependency] private readonly IResiliencePipelineFactory _resiliencePipelineFactory; [IntroduceDependency] private readonly IRetryHttpConfiguration _retryHttpConfiguration; public StrategyKind Kind { get; } public RetryAttribute(StrategyKind kind) { Kind = kind; } public override dynamic? OverrideMethod() { ... } public override async Task<dynamic?> OverrideAsyncMethod() { ... } }

And in the application's Startup class I setup the DI:

services.AddSingleton<ILogger>(_ => Log.Logger); services.AddSingleton<IRetryHttpConfiguration>(dataflowConfiguration.RetryHttpConfiguration); services.AddSingleton<IResiliencePipelineFactory, ResiliencePipelineFactory>();

I am trying to use this attribute in an ApiClient class like so:

public class ApiClient(ILogger logger, HttpClient httpClient) { public async Task<IEnumerable<DeliveryEnvelope>> SendMessagesToClient(IEnumerable<IEventMessage> messages) { using (var request = CreateDefaultRequestMessageWithCustomData()) { // Setup `request` properties response = await SendMessageWithRetry(request); // Process `response` } } [Retry(StrategyKind.RetryWithFallback)] private async Task<HttpResponseMessage> SendMessageWithRetry(HttpRequestMessage request) { var response = await _httpClient.SendAsync(request); return response; }

However, when I try to create an instance of ApiClient (e.g., var apiClient = new ApiClient(logger, httpClient);): I get the following exception:

- Message: Value cannot be null. (Parameter 'resiliencePipelineFactory') - Stack Trace: at Company.Product.Shared.ApiClients.ApiClient..ctor(ILogger logger, HttpClient httpClient, IResiliencePipelineFactory resiliencePipelineFactory, IRetryHttpConfiguration retryHttpConfiguration) at Company.Product.Shared.Helpers.Helper.CreateApiClient(ILogger logger, IConfidentialClientApplication confidentialClient) in C:\Product\Company\Product\Company.Product\src\Company.Product.Shared\Helpers\Helper.cs:line 55

I did search the entire solution to confirm the only variable named resiliencePipelineFactory is in the RetryAttribute class.

Also, in the exception message it shows 4 parameters for the ApiClient class (ILogger, HttpClient, IResiliencePipelineFactory, and IRetryHttpConfiguration) even thought I only defined the first two. I am assuming the other two are added by Metalama since they are required for the RetryAttribute, but then how do I create a new instance of ApiClient ?

Do I need to explicitly define the additional two parameters (i.e., IResiliencePipelineFactory, and IRetryHttpConfiguration) in the ApiClient constructor? If so, how should they be stored/passed to the RetryAttribute as the ApiClient class itself has no use for these two parameters?

This is my first attempt at using Metalama so I am probably missing/misunderstanding something basic so any help/guidance would be greatly appreciated.

Read Entire Article