I can register a grpc client in DI containter and add an interceptor usin the following code.
builder.Services.AddSingleton<MyInterceptor>();
builder.Services
.AddGrpcClient<MyService.MyServiceClient>()
.AddInterceptor<MyInterceptor>();
However, the above solution doesn’t work if there is a parameter in MyInterceptor
‘s constructor:
public sealed class MyInterceptor : Interceptor
{
private readonly int _parameter;
public MyInterceptor (int parameter)
{
_parameter = parameter;
}
// more stuff here
}
No I have to use less elegant way of interceptor registration:
builder.Services
.AddGrpcClient<MyService.MyServiceClient>()
.AddInterceptor(() => new MyInterceptor(1));
which doesn’t seem very nice to me. Also this solution is not very optimal when I need many interceptors with the same parameter value as it leads to unneccessary memory consumption.
Thus, I decided to use a factory pattern to reuse interceptors with the same parameter value.
public class MyInterceptorPool
{
private readonly Dictionary<int, MyInterceptor> _pool;
public MyInterceptorPool()
{
_pool = [];
}
public MyInterceptor GetOrAddMyInterceptor(int parameter)
{
if (_pool.TryGetValue(parameter, out var value))
return value;
value = new MyInterceptor(parameter);
_pool.Add(parameter, value);
return value;
}
}
Now I can register my factory as a Singleton and use it to add interceptors like so:
var interceptorPool = services.BuildServiceProvider().GetRequiredService<GrpcDeadlineInterceptorPool>();
builder.Services
.AddGrpcClient<MyService.MyServiceClient>()
.AddInterceptor(() => interceptorPool.GetOrAddDeadlineInterceptor(10));
or alternatively
builder.Services
.AddGrpcClient<MyService.MyServiceClient>()
.AddInterceptor(sp => sp.GetRequiredService<MyInterceptorPool>().GetOrAddDeadlineInterceptor(10));
While this approach solves the issue, i wonder if there’s a more elegant solution? Perhaps using keyed service registration?
Additionally, I’m uncertain whether using aDictionary
in MyInterceptorPool
is appropriate? Perhaps I should go with ConcurrentDictionary
if ASP .NET Core has some multithreading application configuration.
Any thoughts and comments are highly appreciated.