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; }
}
Open generic types aren't checked The service provider validation completely skips over the open generic registration, so it never detects the missing DataService dependency. The app starts up without errors, and will throw a runtime exception if you try to request a ForecastService<T> .
Session state. Session state is an ASP.NET Core scenario for storage of user data while the user browses a web app. Session state uses a store maintained by the app to persist data across requests from a client. The session data is backed by a cache and considered ephemeral data.
IServiceCollection is the collection of the service descriptors. We can register our services in this collection with different lifestyles (Transient, scoped, singleton) IServiceProvider is the simple built-in container that is included in ASP.NET Core that supports constructor injection by default.
To check, right click on dependencies and choose manage NuGet Packages. And in the update tab, you'll see a list of packages which are available for updates. Like in this case, there is an update available for the “Microsoft. AspNetCore.
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;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With