admin管理员组文章数量:1312678
Due to some restrictions on development when using .NET 8, I need to manage some reusable service. Those need to be either transient or singleton, but 1 of 3 service is depend on the rest.
public static IServiceCollection SetupLoggerFactory(this IServiceCollection services)
{
services.AddSingleton<ILoggerFactory>(new LoggerFactory());
return services;
}
public static IServiceCollection SetupKafkaProducerForFoo(this IServiceCollection services, IConfiguration config)
{
services.AddSingleton<IProducerService>(new ProducerService());
return services;
}
The last service
public static IServiceCollection GetAppLogger(this IServiceCollection services, IServiceProvider serviceProvider)
{
services.AddSingleton<IAppLogger<Badboy.Models.LoggingEvent>>
(new LoggerAdapter<Badboy.Models.LoggingEvent>(
serviceProvider.GetService<ILoggerFactory>(), serviceProvider.GetService<IProducerService>()));
return services;
}
I need to pass the Service provider argument, but I don't know how.
The startup.cs
file:
var builder = WebApplication.CreateBuilder(args);
builder.Services.SetupLoggerFactory();
builder.Services.SetupKafkaProducerForFoo(builder.Configuration);
builder.Services.GetAppLogger(missingArg);
Somehow I cannot get the getRequiredService
method, but when I do
var serviceProvider = app.Services;
builder.Services.GetAppLogger(serviceProvider);
it throws an error:
Unhandled exception. System.InvalidOperationException: The service collection cannot be modified because it is read-only.
at Microsoft.Extensions.DependencyInjection.ServiceCollection.ThrowReadOnlyException()
at Microsoft.Extensions.DependencyInjection.ServiceCollection.System.Collections.Generic.ICollection<Microsoft.Extensions.DependencyInjection.ServiceDescriptor>.Add(ServiceDescriptor item)
at Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(IServiceCollection services, Type serviceType, Object implementationInstance)
Due to some restrictions on development when using .NET 8, I need to manage some reusable service. Those need to be either transient or singleton, but 1 of 3 service is depend on the rest.
public static IServiceCollection SetupLoggerFactory(this IServiceCollection services)
{
services.AddSingleton<ILoggerFactory>(new LoggerFactory());
return services;
}
public static IServiceCollection SetupKafkaProducerForFoo(this IServiceCollection services, IConfiguration config)
{
services.AddSingleton<IProducerService>(new ProducerService());
return services;
}
The last service
public static IServiceCollection GetAppLogger(this IServiceCollection services, IServiceProvider serviceProvider)
{
services.AddSingleton<IAppLogger<Badboy.Models.LoggingEvent>>
(new LoggerAdapter<Badboy.Models.LoggingEvent>(
serviceProvider.GetService<ILoggerFactory>(), serviceProvider.GetService<IProducerService>()));
return services;
}
I need to pass the Service provider argument, but I don't know how.
The startup.cs
file:
var builder = WebApplication.CreateBuilder(args);
builder.Services.SetupLoggerFactory();
builder.Services.SetupKafkaProducerForFoo(builder.Configuration);
builder.Services.GetAppLogger(missingArg);
Somehow I cannot get the getRequiredService
method, but when I do
var serviceProvider = app.Services;
builder.Services.GetAppLogger(serviceProvider);
it throws an error:
Share Improve this question edited Feb 1 at 7:26 marc_s 756k184 gold badges1.4k silver badges1.5k bronze badges asked Feb 1 at 6:41 Adi PrasetyoAdi Prasetyo 1,0421 gold badge16 silver badges43 bronze badgesUnhandled exception. System.InvalidOperationException: The service collection cannot be modified because it is read-only.
at Microsoft.Extensions.DependencyInjection.ServiceCollection.ThrowReadOnlyException()
at Microsoft.Extensions.DependencyInjection.ServiceCollection.System.Collections.Generic.ICollection<Microsoft.Extensions.DependencyInjection.ServiceDescriptor>.Add(ServiceDescriptor item)
at Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(IServiceCollection services, Type serviceType, Object implementationInstance)
1 Answer
Reset to default 1You can use AddSingleton
accepting lambda:
services.AddSingleton<IAppLogger<Badboy.Models.LoggingEvent>>
(sp => new LoggerAdapter<Badboy.Models.LoggingEvent>(
sp.GetService<ILoggerFactory>(), sp.GetService<IProducerService>()))
So you will not need to pass the service provider to the GetAppLogger
(arguably it should be AddAppLogger
) and you can call it before invoking the builder.Build
which makes the service collection immutable (hence the exception).
Note that based on the provided code just doing:
services.AddSingleton<IAppLogger<Badboy.Models.LoggingEvent>,
LoggerAdapter<Badboy.Models.LoggingEvent>>();
Should also do the trick.
Or using open generic registration:
services.AddSingleton(typeof(IAppLogger<>), typeof(LoggerAdapter<>));
本文标签:
版权声明:本文标题:c# - How to create singleton service which depend on another service, with passing IServiceProvider? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741883606a2402893.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论