首页 > 解决方案 > 在 ASP.NET Core 3.1 的 Startup.cs 中注入服务

问题描述

我正在开发一个 .NET Core 3.1 应用程序。我有一个要求,我必须在 Startup.cs 中注入服务。我的代码是:

程序.cs:

public class Program
    {
        public static void Main(string[] args)
        {
            CreateHostBuilder(args).Build().Run();
        }

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureServices(servicesCollection =>
                {
                    servicesCollection.AddScoped<IUnauthorizedAccessService, UnauthorizedAccessService>();
                })
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseStartup<Startup>();
                });
    }

启动.cs:

public Startup(IConfiguration configuration, IUnauthorizedAccessService unauthorizedAccessService)
{
        Configuration = configuration;
        _unauthorizedAccessService = unauthorizedAccessService;
}

public IConfiguration Configuration { get; }
public IUnauthorizedAccessService _unauthorizedAccessService { get; set; }

当我运行代码时,我得到以下异常:

Unable to resolve service for type 'Interface.Service.IUnauthorizedAccessService' while attempting to activate 'Website.Startup'.'

如何在 Startup.cs 中注入服务?我什至尝试过它的Configure方法。但是,我在存储库级别遇到了异常。代码:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IUnauthorizedAccessService unauthorizedAccessService)
        {
            _unauthorizedAccessService = unauthorizedAccessService;

            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");
                // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
                app.UseHsts();
            }
            app.UseHttpsRedirection();
            app.UseStaticFiles();
            app.UseSession();
            app.UseRouting();

            app.UseAuthentication();
            app.UseAuthorization();
            app.UseCookiePolicy(new CookiePolicyOptions
            {
                MinimumSameSitePolicy = SameSiteMode.Strict,
            });

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllerRoute(
                    name: "default",
                    pattern: "{controller=User}/{action=Index}/{id?}");
            });
        }

我有一个RegisterDatabaseConfigureServices. 代码:

private void RegisterDatabase(IServiceCollection services)
        {
            services.AddDbContext<TrainingContext>(options =>
                    options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
        }

服务代码为:

public class UnauthorizedAccessService : IUnauthorizedAccessService
    {
        private readonly IEventLogRepository _eventLogRepository;
        public UnauthorizedAccessService(IEventLogRepository eventLogRepository)
        {
            _eventLogRepository = eventLogRepository;
        }

        public async Task<BaseResponse> LogUnauthorizedAccessInDB(string user, string url, string sessionId)
        {
            try
            {
                EventLog eventLog = new EventLog();
                eventLog.Httpsession = sessionId;
                eventLog.AppUserName = user;
                eventLog.EventDateTime = DateTime.Now;
                eventLog.MessageLevel = 3;
                eventLog.Message = url;

                await _eventLogRepository.Add(eventLog);
            }
            catch(Exception ex)
            {

            }

            return HelperService.Response(null, null);
        }
    }

添加对象时,我得到了异常

Cannot access a disposed context instance. A common cause of this error is disposing a context instance that was resolved from dependency injection and then later trying to use the same context instance elsewhere in your application. This may occur if you are calling 'Dispose' on the context instance, or wrapping it in a using statement. If you are using dependency injection, you should let the dependency injection container take care of disposing context instances.
Object name: 'TrainingContext'.

我所有的其他存储库都在工作,但仅在此时出现异常。可能的问题是什么?任何帮助将非常感激。

基本上,我想要实现的是我想在数据库中记录对我网站的未经授权的访问。代码是:

services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
                .AddCookie(o =>
                {
                    o.AccessDeniedPath = "/Home/Error";
                    o.LoginPath = "/Login";
                    o.SlidingExpiration = false;
                    o.Events = new CookieAuthenticationEvents
                    {
                        //OnRedirectToAccessDenied = new Func<RedirectContext<CookieAuthenticationOptions>, Task>(context =>

                        OnRedirectToAccessDenied = new Func<RedirectContext<CookieAuthenticationOptions>, Task>(test)
                    };
                });

测试方法是:

private async Task<Task> test (RedirectContext<CookieAuthenticationOptions> context)
        {
            string user = context.HttpContext.User.Identity.Name;
            string url = "/" + context.Request.Host.Value + "/" + context.Request.RouteValues["controller"] + "/" + context.Request.RouteValues["action"];
            string sessionId = context.HttpContext.Session.Id;

            await _unauthorizedAccessService.LogUnauthorizedAccessInDB(user, url, sessionId);

            context.Response.Redirect("/Home/Error");
            return context.Response.CompleteAsync();
        }

标签: c#asp.net-core-3.1

解决方案


Startup.cs专为配置自己的服务和管道配置而设计。您不能仅仅因为它们尚未配置而在构造函数中注入您的自定义服务。

文档

主机提供可用于 Startup 类构造函数的服务。该应用程序通过 ConfigureServices 添加其他服务。主机和应用程序服务在配置和整个应用程序中都可用。


推荐阅读