在 .NET CORE 中为多个控制器使用公共基础控制器时如何处理依赖注入

How to handle dependency injection when using a common base controller for multiple controllers in .NET CORE

我有一个 UserController 和一个 BaseController,其中注入了一些函数和依赖项,如下所示。 BaseController 在多个控制器之间共享。但是所有控制器都不需要从 BaseController 注入的所有依赖项。 Controller1 需要依赖项 D1 和 D2,但 Controller2 只需要来自 BaseController 的 D1。我怎样才能做到这一点?

在下面的代码中,UserController 不需要从基础注入的 webHostEnvironment,但我需要注入它,因为它存在于 BaseController 中,否则 Visual Studio 会抛出缺少依赖项的编译器错误。如果需要其他详细信息来解决问题,请告诉我。

用户控制器

using MyApp.Data;
using MyApp.Models;
using MyApp.Models.ViewModels;
using MyApp.Utilities;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Identity.UI.Services;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;

namespace MyApp.Controllers
{
    [Authorize]
    public class UserController : BaseController
    {
        private readonly ApplicationDbContext db;
        private readonly ILogger<UserController> logger;
        private readonly RoleManager<IdentityRole> roleManager;
        private readonly IEmailSender emailSender;

        public UserController(  ApplicationDbContext db,
                                ILogger<UserController> logger,
                                UserManager<ApplicationUser> userManager,
                                RoleManager<IdentityRole> roleManager,
                                IEmailSender emailSender,
                                IWebHostEnvironment webHostEnvironment) : base (userManager, webHostEnvironment)
        {
            this.db = db;
            this.logger = logger;
            this.roleManager = roleManager;
            this.emailSender = emailSender;
        }

        [HttpGet]
        public IActionResult Index()
        {
            var userList = userManager.Users;
            return View(userList);
        }

        [HttpGet]
        public async Task<IActionResult> Read(string? id)
        {
            var user = await userManager.FindByIdAsync(id);
            if (user == null)
            {
                return RecordNotFound();
            }
            UserViewModel model = new()
            {
                Id = user.Id,
                FirstName = user.FirstName,
                LastName = user.LastName,
                UserName = user.UserName,
                Email = user.Email,
                PhoneNumber = user.PhoneNumber,
            };
            return View(model);
        }
    //And Some more Action Methods for the controller
    }
}

基础控制器

using MyApp.Models;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;

namespace MyApp.Utilities
{
    [Authorize]
    public class BaseController : Controller
    {
        protected readonly UserManager<ApplicationUser> userManager;
        protected readonly IWebHostEnvironment webHostEnvironment;
        
        public BaseController(  UserManager<ApplicationUser> userManager,
                                IWebHostEnvironment webHostEnvironment)
        {
            this.userManager = userManager;
            this.webHostEnvironment = webHostEnvironment;
            
        }

        [HttpGet] [HttpPost]
        public IActionResult RecordNotFound()
        {
            TempData[HelperStatic.ErrorMessage] = HelperStatic.recordNotFoundMsg;
            return View("Index");
        }

        [HttpPost]
        public IActionResult SaveNew()
        {
            TempData[HelperStatic.SuccessMessage] = HelperStatic.recordSavedMsg;
            return RedirectToAction("Create");
        }
        
        //And Many other Reusable Methods for all controllers
    }
}

看来您的基本控制器中发生的事情太多了。

如果您在基本控制器中有不适用于所有人的操作,那么它们就存在于错误的位置。

例如(根据您提供的内容),此操作看起来应该可以执行,例如在错误控制器上:

[HttpGet] [HttpPost]
public IActionResult RecordNotFound()
{
    TempData[HelperStatic.ErrorMessage] = HelperStatic.recordNotFoundMsg;
    return View("Index");
}

然后你重定向到 'Error/RecordNotFound' 而不是在每个继承控制器中都存在它。

您不能依赖于您的基础构造函数,而这些依赖项也没有注入到子 类 上。如果这给你带来了麻烦,那是因为基地里发生的事情太多了!