简体   繁体   English

在 ASP.NET Core 3.1 的 Startup.cs 中注入服务

[英]Inject a service in Startup.cs in ASP.NET Core 3.1

I am working on a .NET Core 3.1 application.我正在开发 .NET Core 3.1 应用程序。 I have a requirement where i have to inject a service in Startup.cs.我有一个要求,我必须在 Startup.cs 中注入服务。 My code is:我的代码是:

Program.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>();
                });
    }

Startup.cs:启动.cs:

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

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

When i run the code, i get the following exception:当我运行代码时,我得到以下异常:

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

How can i inject the service in Startup.cs?如何在 Startup.cs 中注入服务? I have even tried it getting in Configure method.我什至尝试过使用Configure方法。 But then, i get the exception at repository level.但是,我在存储库级别遇到了异常。 Code:代码:

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?}");
            });
        }

I have a method RegisterDatabase which is being called from ConfigureServices .我有一个从ConfigureServices调用的方法RegisterDatabase Code:代码:

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

Service code is:服务代码为:

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);
        }
    }

When Adding the object, i get the exception添加 object 时,出现异常

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'.

All of my other repositories are working but, getting exception only at this point.我所有的其他存储库都在工作,但仅在此时出现异常。 What can be the possible issue?可能的问题是什么? Any help would be much appreciated.任何帮助将非常感激。

Basically, what i am trying to achieve is that i want to log unauthorized access to my site in Database.基本上,我想要实现的是我想在数据库中记录对我网站的未经授权的访问。 Code is:代码是:

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)
                    };
                });

test method is:测试方法是:

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();
        }

Startup.cs is designed for configuring own services and pipeline configuration. Startup.cs旨在配置自己的服务和管道配置。 You can not inject your custom services in constructor just because they are not configured yet.您不能仅仅因为它们尚未配置而在构造函数中注入您的自定义服务。

Docs:文件:

The host provides services that are available to the Startup class constructor.主机提供可用于 Startup class 构造函数的服务。 The app adds additional services via ConfigureServices.该应用程序通过 ConfigureServices 添加其他服务。 Both the host and app services are available in Configure and throughout the app.主机和应用程序服务在配置和整个应用程序中都可用。

You need to create a scoped object that implements CookieAuthenticationEvents .您需要创建一个实现CookieAuthenticationEvents For example:例如:

using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using System.Threading.Tasks;

namespace MyApplication.Services
{
    public class MyCookieAuthenticationEvents : CookieAuthenticationEvents
    {
        private readonly IUnauthorizedAccessService _unauthorizedAccessService;

        public MyCookieAuthenticationEvents(
            IUnauthorizedAccessService unauthorizedAccessService)
        {
            _unauthorizedAccessService = unauthorizedAccessService;
        }

        public override Task RedirectToAccessDenied(
            RedirectContext<CookieAuthenticationOptions> context)
        {
            // TODO: you can use _unauthorizedAccessService here
            return base.RedirectToAccessDenied(context);
        }
    }
}

To inject this, you'd do it as so:要注入它,您可以这样做:

services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
    .AddCookie(options =>
    {
        options.EventsType = typeof(MyCookieAuthenticationEvents);
    });

services.AddScoped<MyCookieAuthenticationEvents>();
services.AddScoped<IUnauthorizedAccessService, UnauthorizedAccessService>();

Make sure you remove that IUnauthorizedAccessService from your program.cs .确保从您的program.cs中删除该IUnauthorizedAccessService You don't inject there.你不在那里注射。 You inject in your Configure method.您注入您的Configure方法。

This is how you do proper dependency injection.这就是你如何进行正确的依赖注入。 You don't do what the accepted answer is doing.你不做接受的答案正在做的事情。 That is probably one of the most unorthodox things I have ever seen in a long time.这可能是我很长一段时间以来见过的最不正统的事情之一。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何将 ASP.NET Core 3.1 中 Startup.cs 中的代码移动到 ASP.NET Core 6? - How to move code in Startup.cs in ASP.NET Core 3.1 to ASP.NET Core 6? 集成测试中的自定义 WebApplicationFactory 未在 Startup.cs 中注册服务(ASP.NET Core 3.1) - Custom WebApplicationFactory in integration testing not registering services in Startup.cs (ASP.NET Core 3.1) 如何在startup.cs的ConfigureServices方法中正确注入DbContext实例(ASP.net core 1.1)? - How to inject DbContext instance in the ConfigureServices method of startup.cs correctly (ASP.net core 1.1)? 在ASP.NET CORE中的Startup.cs中设置动态变量 - Set Dynamic Variables in Startup.cs in ASP.NET CORE 如何在 ASP.NET Core 中的 Startup.cs 中注册 RoleManager - How to register RoleManager in Startup.cs in ASP.NET Core ASP.NET Core中的Startup.cs中kestrel关闭function - Kestrel shutdown function in Startup.cs in ASP.NET Core 在 Startup.cs 之外更新 asp.net 核心身份验证 - Update asp.net core Authentication outside of Startup.cs 从 startup.cs asp.net 内核重定向用户 - Redirect user from startup.cs asp.net core 如何删除 Startup.cs 中的 WebDav ASP.NET Core - How to remove WebDav in Startup.cs ASP.NET Core 在Asp.net Core中的startup.cs中获取用户名 - Get username within startup.cs in Asp.net core
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM