首页 > 解决方案 > 如何使用依赖注入在启动时启动自定义服务

问题描述

如何从需要依赖注入的 ASP.NET Core 中的 startup.cs 启动自定义服务类?

我使用的服务是一个 Telegram Message 服务,它使用一些带有传入数据的 websocket。我的服务:

public class TelegramService 
{
    private IUserRepository _userRepository;
    private IAsyncRepository<Coin> _coinRepository;

    public TelegramService(IUserRepository userRepository, ICoinRepository coinRepository)
    {
        _userRepository = userRepository;
        _coinRepository = coinRepository;

        this.Start();
    }

    public async Task Start()
    {
        List<User> users = await _userRepository.GetAllUsers();
        List<Coin> coins = new List<Coin>(await _coinRepository.ListAllAsync());
        foreach (var coin in coins)
        {
            TelegramMessageService telegramMessageService = new TelegramMessageService(users, coin.Type);
        }
    }

我的创业课。我做了 services.AddSingleton(); 但显然我错过了一些东西。

     public void ConfigureServices(IServiceCollection services)
        {
            AddSwagger(services);

            services.AddApplicationServices();
            services.AddInfrastructureServices(Configuration);
             services.AddDbContext<CryptoGuruDbContext>(options => options.UseSqlServer(configuration.GetConnectionString("CryptoGuruConnectionString"),
                b => b.MigrationsAssembly(typeof(CryptoGuruDbContext).Assembly.FullName)));

            services.AddIdentity<User, IdentityRole>()
                .AddEntityFrameworkStores<CryptoGuruDbContext>().AddDefaultTokenProviders();

            services.AddScoped(typeof(IAsyncRepository<>), typeof(BaseRepository<>));
            services.AddScoped<IUserRepository, UserRepository>();
            services.AddScoped<ICoinRepository, CoinRepository>();

            services.AddControllers();

            services.AddCors(options =>
            {
                options.AddPolicy("Open", builder => builder.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod());
            });

            // Here is my service
            services.AddSingleton<TelegramService>();
            //services.AddTransient<TelegramService>();
            //services.AddScoped<TelegramService>();

        }

我试过AddTrasientAddScoped。两者都不会从构造函数中触发 Start() 方法。AddSingleton 只是给出一个错误:

System.AggregateException
  HResult=0x80131500
  Message=Some services are not able to be constructed (Error while validating the service descriptor 'ServiceType: crypto_guru.Application.Services.TelegramService Lifetime: Singleton ImplementationType: crypto_guru.Application.Services.TelegramService': Cannot consume scoped service 'crypto_guru.Application.Contracts.Persistence.IUserRepository' from singleton 'crypto_guru.Application.Services.TelegramService'.)
  Source=Microsoft.Extensions.DependencyInjection
  StackTrace:
   at Microsoft.Extensions.DependencyInjection.ServiceProvider..ctor(IEnumerable`1 serviceDescriptors, IServiceProviderEngine engine, ServiceProviderOptions options)
   at Microsoft.Extensions.DependencyInjection.ServiceCollectionContainerBuilderExtensions.BuildServiceProvider(IServiceCollection services, ServiceProviderOptions options)
   at Microsoft.Extensions.DependencyInjection.DefaultServiceProviderFactory.CreateServiceProvider(IServiceCollection containerBuilder)
   at Microsoft.Extensions.Hosting.Internal.ServiceFactoryAdapter`1.CreateServiceProvider(Object containerBuilder)
   at Microsoft.Extensions.Hosting.HostBuilder.CreateServiceProvider()
   at Microsoft.Extensions.Hosting.HostBuilder.Build()
   at crypto_guru.Api.Program.<Main>d__0.MoveNext() in D:\Clouds\OneDrive\Documenten\GitHub\crypto-guru\backend\X-Copter.Api\Program.cs:line 27

  This exception was originally thrown at this call stack:
    [External Code]

Inner Exception 1:
InvalidOperationException: Error while validating the service descriptor 'ServiceType: crypto_guru.Application.Services.TelegramService Lifetime: Singleton ImplementationType: crypto_guru.Application.Services.TelegramService': Cannot consume scoped service 'crypto_guru.Application.Contracts.Persistence.IUserRepository' from singleton 'crypto_guru.Application.Services.TelegramService'.

Inner Exception 2:
InvalidOperationException: Cannot consume scoped service 'crypto_guru.Application.Contracts.Persistence.IUserRepository' from singleton 'crypto_guru.Application.Services.TelegramService'.

对不起,如果这是一个菜鸟问题,但我真的找不到做这样的事情的答案。

标签: c#asp.netasp.net-core.net-corestartup

解决方案


问题是 TelegramService 和 IUserRepository 之间存在终身不匹配。TelegramService 是一个单例并且 IUserRepository 是作用域的。如果您尝试将作用域服务注入单例,那么作用域服务本质上就变成了单例。这是一个强制依赖的例子。您也应该将 TelegramService 设为范围。


推荐阅读