在 .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' 而不是在每个继承控制器中都存在它。
您不能依赖于您的基础构造函数,而这些依赖项也没有注入到子 类 上。如果这给你带来了麻烦,那是因为基地里发生的事情太多了!
我有一个 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' 而不是在每个继承控制器中都存在它。
您不能依赖于您的基础构造函数,而这些依赖项也没有注入到子 类 上。如果这给你带来了麻烦,那是因为基地里发生的事情太多了!