简体   繁体   中英

AspNetCore unable to resolve service

I'm adding Microsoft.AspNetCore.Identity to a project, and I get

InvalidOperationException: Unable to resolve service for type 'Microsoft.AspNetCore.Identity.SignInManager'1[Web.Security.Entities.IUser'1[System.Int32]]' while attempting to activate 'Web.Security.Services.SecurityService'2[Web.Security.Entities.IUser'1[System.Int32],System.Int32]'.

Exception is copypasted from postman, it encoded some symbols. Here's my Startup.cs:

public class Startup
{
    ServiceProvider serviceProvider;
    IConfigurationRoot configurationRoot;
    public IConfiguration Configuration { get; }
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;

        configurationRoot = new ConfigurationBuilder()
            .AddJsonFile("appsettings.json", optional: false)
            .AddIniFile("3CXPhoneSystem.ini")
            .Build();
    }
    // This method gets called by the runtime. Use this method to add services to the container.
    // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
    public void ConfigureServices(IServiceCollection services)
    {
        serviceProvider = services
                  .AddLogging((builder) => builder.SetMinimumLevel(LogLevel.Trace))            
           .AddSingleton<ISecurityService, SecurityService<IUser<int>, int>>()
                 .AddSingleton<ITaskService, TaskService>()
                 .AddTransient<IEmailSender, EmailSender>()
                 .AddSingleton<ITranslation, Translation>()
           .BuildServiceProvider();
        services.AddDbContext<SecurityDbContext>(options =>
        options.UseSqlServer(Configuration.GetConnectionString("dataContext")));

        services.AddIdentity<Web.Security.Entities.User<int>, IdentityRole>()
        .AddEntityFrameworkStores<SecurityDbContext>()
        .AddDefaultTokenProviders();

        services.AddCors(o => o.AddPolicy("CorsPolicy", builder =>
        {
            builder
            .AllowAnyMethod()
            .AllowAnyHeader()
            .WithOrigins("http://localhost:52170");
        }));
        services.AddMvc();

        services.Configure<IdentityOptions>(options =>
        {
            // Password settings
            options.Password.RequireDigit = true;
            options.Password.RequiredLength = 8;
            options.Password.RequireNonAlphanumeric = false;
            options.Password.RequireUppercase = true;
            options.Password.RequireLowercase = false;
            options.Password.RequiredUniqueChars = 6;

            // Lockout settings
            options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(30);
            options.Lockout.MaxFailedAccessAttempts = 10;
            options.Lockout.AllowedForNewUsers = true;

            // User settings
            options.User.RequireUniqueEmail = true;
        });


    }



    // 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.UseDefaultFiles();
        app.UseStaticFiles();

        app.Use(async (context, next) =>
        {
            await next();

            if (context.Response.StatusCode == 404 && !Path.HasExtension(context.Request.Path.Value) && !context.Request.Path.Value.StartsWith("api"))
            {
                context.Response.Redirect("/");
            }
        });


        app.UseMvc(routes =>
        {
            routes.MapRoute(name: "DefaultApi", template: "api/{controller}/{action}/{id?}");
            routes.MapRoute("RouteToAngular", "{*url}", defaults: new { controller = "Route", action = "Index" });

        });

        app.UseAuthentication();

        app.UseCors("CorsPolicy");
    }

Here, SecurityService is a class that will handle registration/login/other identity related requests, it looks like this

public class SecurityService<TUser, TKey> : ISecurityService where TUser : class, IUser<TKey>
{
    SignInManager<TUser> signInManager;
    IConfiguration configuration;
    private readonly IHttpContextAccessor httpContextAccessor;
    UserManager<TUser> userManager;
    IEmailSender emailSender;
    IUrlHelper urlHelper;
    ISession session;
    ILogger<SecurityService<TUser, TKey>> logger;
    ITranslation translation; 

    public SecurityService(
        SignInManager<TUser> signInManager,
        UserManager<TUser> userManager,
        IConfiguration configuration,
        IHttpContextAccessor httpContextAccessor,
        IEmailSender emailSender,
        IUrlHelper urlHelper,
        ISession session,
        ILogger<SecurityService<TUser, TKey>> logger,
        ITranslation translation)
    {
        this.signInManager = signInManager;
        this.userManager = userManager;
        this.configuration = configuration;
        this.httpContextAccessor = httpContextAccessor;
        this.urlHelper = urlHelper;
        this.session = session;
        this.logger = logger;
        this.translation = translation;
        this.emailSender = emailSender;
    }

IUser.cs:

public interface IUser<TKey>
{
    TKey Id { get; set; }
    string UserName { get; set; }
    string Email { get; set; }
    bool EmailConfirmed { get; set; }
}

You need to use the IdentityBuilder extension method AddSignInManager explicitly.

services.AddIdentity<Web.Security.Entities.User<int>, IdentityRole>()
    .AddEntityFrameworkStores<SecurityDbContext>()
    // Replace ApplicationUser with your concrete user class
    .AddSignInManager<SignInManager<ApplicationUser>>() 
    .AddDefaultTokenProviders();

If you need access to it in your security service then you can inject it:

public class SecurityService<TUser, TKey> ...
{
    public SecurityService(SignInManager<ApplicationUser> signInManager)
    {
        this.signInManager = signInManager;
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM