首页 > 解决方案 > System.InvalidOperationException:尝试激活“HomeController”时无法解析“LoginManager”类型的服务

问题描述

请原谅我可能会问这个问题,但我只是使用 ASP.NET MVC/C# 的初学者。我和其他 3 位同学在一个小组项目中,但我们似乎无法弄清楚如何解决这个问题。

我正在尝试运行这个项目,但它给了我以下错误:

“InvalidOperationException:尝试激活 >'B3.Controllers.HomeController' 时无法解析类型 >'BusinessLogic.LoginManager' 的服务。

Microsoft.Extensions.DependencyInjection.ActivatorUtilities.GetService(IServ>iceProvider sp, Type type, Type requiredBy, bool >isDefaultParameterRequired)"

我们有两个数据库连接,有两个单独的 dbContext 类。那么我可以从错误中看出什么(如果我没记错的话)它在依赖注入方面存在一些问题?

如果代码有点乱,我很抱歉。如果您也想看其他课程,那么我愿意分享它们。

家庭控制器

public class HomeController : Controller
{
    private LoginManager loginManager;

    public HomeController(LoginManager login)
    {
        loginManager = login;
    }

    public IActionResult Login()
    {
        return View();
    }

    [HttpPost]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> Login(LoginModel loginModel)
    {
        if (ModelState.IsValid)
        {
            if (await loginManager.LoginUser(loginModel))
            {
                return Redirect("/Overview/Index");
            }
            else
            {
                ModelState.AddModelError(string.Empty, "Invalid login  attempt.");
                return View(loginModel);
            }
        }
        else
        {
            return View("Login", loginModel);
        }

    }

    public async Task<IActionResult> Logout()
    {
        await loginManager.LogOut();
        return Redirect("/");
    }

    public IActionResult SignUp()
    {
        return View("AddUser");
    }

    [HttpPost]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> SignUp(LoginModel loginModel)
    {
        if (ModelState.IsValid)
        {
            string message = await loginManager.SignUp(loginModel);
            if (message.Equals("Success"))
            {
                return Redirect("/");
            }
            else
            {
                ModelState.AddModelError(string.Empty, message);
                return View("AddUser");
            }
        }
        else
        {
            return View();
        }
    }
}

登录管理器

public class LoginManager
{
    private UserManager<IdentityUser> _userManager;
    private SignInManager<IdentityUser> _signInManager;
    private IEmployeeRepository _employeeRepository;

    public LoginManager(IEmployeeRepository employeeRepo, UserManager<IdentityUser> userManager, SignInManager<IdentityUser> signInManager)
    {
        _employeeRepository = employeeRepo;
        _userManager = userManager;
        _signInManager = signInManager;
    }

    public async Task<bool> LoginUser(LoginModel loginModel)
    {
        IdentityUser applicationUser = await _userManager.FindByNameAsync(loginModel.Name);

        if (applicationUser != null)
        {

            await _signInManager.SignOutAsync();
            if ((await _signInManager.PasswordSignInAsync(applicationUser, loginModel.Password, false, false)).Succeeded)
            {
                return true;
            }

        }

        return false;
    }

    public async Task LogOut()
    {
        await _signInManager.SignOutAsync();
    }

    public async Task<string> SignUp(LoginModel loginModel)
    {
        IdentityUser applicationUser = new IdentityUser()
        {
            UserName = loginModel.Name,
            Email = loginModel.Email
        };

        Employee em = _employeeRepository.GetEmployee(e => e.Email == loginModel.Email);
        if (em == null)
        {
            return "Opgegeven email adres niet bekend";
        }
        else
        {
            if (em.LabelId == loginModel.LabelId && em.Name == loginModel.EmployeeName)
            {
                var result = await this._userManager.CreateAsync(applicationUser, loginModel.Password);
                if (result.Succeeded)
                {
                    IdentityUser createUser =
                        this._userManager.Users.FirstOrDefault(u => u.Email.Equals(loginModel.Email));

                    return "Success";
                }

                foreach (var error in result.Errors)
                {
                    return "Geen geldige registratie gegevens.";
                }
            }
            else
            {
                return "Opgegeven naam en id zijn niet kloppend bij het email adres.";
            }
        }

        return "Er is iets misgegaan tijdens de registratie";
    }
}

DBEmployeeRepository

public class DBEmployeeRepository : IEmployeeRepository
{
    private EmployeeCollection employeeCollection;
    private readonly DbContextOptions<AppDbContext> _contextOptions;

    public DBEmployeeRepository(DbContextOptions<AppDbContext> contextOptions)
    {
        _contextOptions = contextOptions;

        using (var context = new AppDbContext(_contextOptions))
        {
            employeeCollection = new EmployeeCollection()
            {
                AllEmployees = context.Employees
                    .Include("Contacts.Contact")
                    .Include("Deals.EmployeeDeal")
                    .Include("Label.Label")
                    .ToList()
            };
        }
    }

    public Employee GetEmployee(Func<Employee, bool> lambda)
    {
        Employee employee = employeeCollection.AllEmployees.FirstOrDefault(lambda);
        return employee;
    }

    public IEnumerable<Employee> GetEmployees()
    {
        return employeeCollection.AllEmployees;
    }

    public IEnumerable<Employee> GetEmployees(Func<Employee, bool> lambda)
    {
        return employeeCollection.AllEmployees.Where(lambda);
    }
}

启动.cs

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.Configure<CookiePolicyOptions>(options =>
        {
            // This lambda determines whether user consent for non-essential cookies is needed for a given request.
            options.CheckConsentNeeded = context => true;
            options.MinimumSameSitePolicy = SameSiteMode.None;
        });

        services.AddDbContext<AppDbContext>(options => 
            options.UseSqlServer(
                Configuration["Data:Project:ConnectionString"]));

        services.AddDbContext<AppIdentityDbContext>(options =>
            options.UseSqlServer(
                Configuration["Data:Identity:ConnectionString"]));

        services.AddIdentity<IdentityUser, IdentityRole>()
            .AddEntityFrameworkStores<AppIdentityDbContext>()
            .AddDefaultTokenProviders();

        services.AddScoped<IEmployeeRepository, DBEmployeeRepository>();
        services.AddScoped<ICompanyRepository, DBCompanyRepository>();
        services.AddScoped<IContactRepository, DBContactRepository>();
        services.AddScoped<IDealRepository, DBDealRepository>();
        services.AddScoped<IInvoiceRepository, DBInvoiceRepository>();
        services.AddScoped<ILabelRepository, DBLabelRepository>();

        services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
    }

    // 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();
        }
        else
        {
            app.UseExceptionHandler("/Error");
            app.UseHsts();
        }

        

        app.UseHttpsRedirection();
        app.UseStaticFiles();
        app.UseAuthentication();
        IdentitySeedData.EnsurePopulated(app);
        app.UseCookiePolicy();
        app.UseMvc(routes =>
        {
            routes.MapRoute(
                name: "default",
                template: "{controller=Home}/{action=Login}/{id?}");
        });
    }
}

标签: asp.net-core-mvc

解决方案


您忽略了注册LoginManager您的服务。

services.AddScoped<LoginManager>();

由于您是学生,因此您应该注意一些非常严重的代码问题。首先,您的存储库完全错误。您几乎不应该使用using上下文,因为它应该保持请求范围。您也不应该在类构造函数中执行查询数据库之类的操作。但是,这样做是有问题的,因为您仅在实例化时捕获数据。如果您继续将实体的其他实例添加到数据库中,您的存储库将不会反映这一点。相反,您应该将上下文注入到您的 repo 的构造函数中,将其保存到只读 ivar,然后直接在您的 repo 方法中使用它。

也就是说,在这里使用存储库模式是一个错误。存储库模式的重点是从应用程序代码中抽象出低级数据库访问(SQL 查询字符串等)。当使用像实体框架这样的 ORM 时,这已经为您完成了。事实上,它DbContext实现了工作单元模式,并且DbSet它上面的每个都是一个存储库。使用 ORM 时,就是您的数据层;创建自己的数据层,该数据层是多余的,只会增加代码的熵。


推荐阅读