首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ASP.NET核心2中的依赖注入

ASP.NET核心2中的依赖注入
EN

Stack Overflow用户
提问于 2018-03-12 18:29:34
回答 2查看 1.2K关注 0票数 2

更新

我将启动更改为:

代码语言:javascript
复制
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Actio.Api.Handlers;
using Actio.Api.Repositories;
using Actio.Common.Auth;
using Actio.Common.Events;
using Actio.Common.Mongo;
using Actio.Common.RabbitMq;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;

namespace Actio.Api
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc();
            services.AddJwt(Configuration);
            services.AddRabbitMq(Configuration);
            services.AddMongoDB(Configuration);
            services.AddScoped<IEventHandler<ActivityCreated>, ActivityCreatedHandler>();
            services.AddScoped<IActivityRepository, ActivityRepository>();

        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            // app.ApplicationServices.GetService<IDatabaseInitializer>().InitializeAsync();

            using (var serviceScope = app.ApplicationServices.CreateScope())
            {
                serviceScope.ServiceProvider.GetService<IDatabaseInitializer>().InitializeAsync();
            }
            app.UseAuthentication();
            app.UseMvc();
        }
    }
}

但是现在我在SubscribeToEvent:中出现了错误,无法解析作用域服务。

代码语言:javascript
复制
'Actio.Common.Events.IEventHandler`1[Actio.Common.Events.ActivityCreated]' from root provider.' 

在我的ServiceHost.cs里。

ServiceHost.cs

代码语言:javascript
复制
using System;
using Actio.Common.Commands;
using Actio.Common.Events;
using Actio.Common.RabbitMq;
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using RawRabbit;

namespace Actio.Common.Services
{
    public class ServiceHost : IServiceHost
    {
        private readonly IWebHost _webHost;

        public ServiceHost(IWebHost webHost)
        {
            _webHost = webHost;
        }

        public void Run() => _webHost.Run();

        public static HostBuilder Create<TStartup>(string[] args) where TStartup : class
        {
            Console.Title = typeof(TStartup).Namespace;
            var config = new ConfigurationBuilder()
                .AddEnvironmentVariables()
                .AddCommandLine(args)
                .Build();
            var webHostBuilder = WebHost.CreateDefaultBuilder(args)
                .UseConfiguration(config)
                .UseStartup<TStartup>();

            return new HostBuilder(webHostBuilder.Build());
        }

        public abstract class BuilderBase 
        {
            public abstract ServiceHost Build();
        }

        public class HostBuilder : BuilderBase
        {
            private readonly IWebHost _webHost;
            private IBusClient _bus;

            public HostBuilder(IWebHost webHost)
            {
                _webHost = webHost;
            }

            public BusBuilder UseRabbitMq()
            {
                _bus = (IBusClient)_webHost.Services.GetService(typeof(IBusClient));

                return new BusBuilder(_webHost, _bus);
            }

            public override ServiceHost Build()
            {
                return new ServiceHost(_webHost);
            }
        }

        public class BusBuilder : BuilderBase
        {
            private readonly IWebHost _webHost;
            private IBusClient _bus; 

            public BusBuilder(IWebHost webHost, IBusClient bus)
            {
                _webHost = webHost;
                _bus = bus;
            }

            public BusBuilder SubscribeToCommand<TCommand>() where TCommand : ICommand
            {
                var handler = (ICommandHandler<TCommand>)_webHost.Services
                    .GetService(typeof(ICommandHandler<TCommand>));
                _bus.WithCommandHandlerAsync(handler);

                return this;
            }

            public BusBuilder SubscribeToEvent<TEvent>() where TEvent : IEvent
            {
                var handler = (IEventHandler<TEvent>)_webHost.Services
                    .GetService(typeof(IEventHandler<TEvent>));
                _bus.WithEventHandlerAsync(handler);

                return this;
            }

            public override ServiceHost Build()
            {
                return new ServiceHost(_webHost);
            }
        }
    }
}

我最近开始用RabbitMQ学习微服务。经过很大的努力,我得到了一个代码示例,但是我无法运行它,因为它给出了错误:"System.InvalidOperationException: 'Cannot resolve scoped service 'Actio.Common.Mongo.IDatabaseInitializer' from root provider.'"

我希望理解这段代码,以便更好地理解Microservices。

Code-Startup.cs

代码语言:javascript
复制
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Actio.Api.Handlers;
using Actio.Api.Repositories;
using Actio.Common.Auth;
using Actio.Common.Events;
using Actio.Common.Mongo;
using Actio.Common.RabbitMq;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;

namespace Actio.Api
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc();
            services.AddJwt(Configuration);
            services.AddRabbitMq(Configuration);
            services.AddMongoDB(Configuration);
            services.AddScoped<IEventHandler<ActivityCreated>, ActivityCreatedHandler>();
            services.AddScoped<IActivityRepository, ActivityRepository>();
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
          //Giving Error in below line


app.ApplicationServices.GetService<IDatabaseInitializer>().InitializeAsync();
                app.UseAuthentication();
                app.UseMvc();
            }
        }
    }

有人能帮忙吗?这样我就可以调试了,我也有了更好的理解。

谢谢

EN

回答 2

Stack Overflow用户

发布于 2018-03-14 10:46:37

下面的错误试图告诉您,您正在将IDatabaseInitializer注册为一个作用域服务,但试图在范围之外访问它。

代码语言:javascript
复制
"System.InvalidOperationException: 'Cannot resolve scoped service 'Actio.Common.Mongo.IDatabaseInitializer' from root provider.'"

尝试创建一个作用域,然后使用以下服务:

代码语言:javascript
复制
using (var serviceScope = app.ApplicationServices.CreateScope())
{
    serviceScope.ServiceProvider.GetService<IDatabaseInitializer>().InitializeAsync();
}
票数 1
EN

Stack Overflow用户

发布于 2020-05-04 14:24:01

解决方案是禁用范围验证。

因此,在第31-32行之间的文件src\actio.common\services\servicehost.cs中添加以下内容:

代码语言:javascript
复制
.UseDefaultServiceProvider(options => options.ValidateScopes = false)

解决这个问题的另一种替代方法是从services.AddScoped转变为services.AddSingleton in program.cs,使用单例也可以避免所有的范围验证。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49242181

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档