gpt4 book ai didi

c# - .Net Core 2.0 中 Controller 和 BaseController 中的依赖注入(inject)重复

转载 作者:可可西里 更新时间:2023-11-01 08:19:02 25 4
gpt4 key购买 nike

如果我在我的 Asp.Net Core 2.0 Web 应用程序中创建一个 BaseController 来封装一些常见的依赖项,它们在实际 Controller 中是否仍然是必需的。

例如,默认 MVC 6 网络应用程序中的标准帐户和管理 Controller 。

public class AccountController : Controller
{
private readonly UserManager<ApplicationUser> _userManager;
private readonly SignInManager<ApplicationUser> _signInManager;
private readonly IEmailSender _emailSender;
private readonly ILogger _logger;

public AccountController(
UserManager<ApplicationUser> userManager,
SignInManager<ApplicationUser> signInManager,
IEmailSender emailSender,
ILogger<AccountController> logger)
{
_userManager = userManager;
_signInManager = signInManager;
_emailSender = emailSender;
_logger = logger;
}
//rest of code removed
}

public class ManageController : Controller
{
private readonly UserManager<ApplicationUser> _userManager;
private readonly SignInManager<ApplicationUser> _signInManager;
private readonly IEmailSender _emailSender;
private readonly ILogger _logger;
private readonly UrlEncoder _urlEncoder;

private const string AuthenicatorUriFormat = "otpauth://totp/{0}:{1}?secret={2}&issuer={0}&digits=6";

public ManageController(
UserManager<ApplicationUser> userManager,
SignInManager<ApplicationUser> signInManager,
IEmailSender emailSender,
ILogger<ManageController> logger,
UrlEncoder urlEncoder)
{
_userManager = userManager;
_signInManager = signInManager;
_emailSender = emailSender;
_logger = logger;
_urlEncoder = urlEncoder;
}
// rest of code removed
}

在我正在构建的自定义 Web 应用程序模板中,我将帐户 Controller 重构为三个不同的 Controller ,RegisterController(它处理与用户注册有关的所有事情)、LoginController(它处理登录和注销),以及平衡到第三个。我将管理 Controller 一分为二,一个 ManagePasswordController(与密码相关的所有内容)和一个 UserManageController(所有其他内容)。

每个的 DI 要求有很多共性,我想将它们放在一个 BaseController 中。看起来像这样?

public abstract class BaseController : Controller
{
private readonly IConfiguration _config;
private readonly IEmailSender _emailSender;
private readonly ILogger _logger;
private readonly SignInManager<ApplicationUser> _signInManager;
private readonly UserManager<ApplicationUser> _userManager;

protected BaseController(IConfiguration iconfiguration,
UserManager<ApplicationUser> userManager,
SignInManager<ApplicationUser> signInManager,
IEmailSender emailSender,
ILogger<ManageController> logger)
{
_config = iconfiguration;
_userManager = userManager;
_signInManager = signInManager;
_emailSender = emailSender;
_logger = logger;
}
//rest of code removed
}

但是好像什么都没做?因为在我看来我仍然必须注入(inject)一切。我不可能是对的(我是 DI 的新手,所以显然不知道)但是 BaseController 应该允许我做 NO DI,这在 BaseController 和 RegisterController 之间很常见。我错了吗?我如何完成我想做的事情?

public class RegisterController : BaseController
{
private const string ConfirmedRegistration = "User created a new account with password.";

private readonly UserManager<ApplicationUser> _userManager;
private readonly SignInManager<ApplicationUser> _signInManager;
private readonly IEmailSender _emailSender;
private readonly ILogger _logger;
private readonly IConfiguration _config;

public RegisterController(
IConfiguration config,
UserManager<ApplicationUser> userManager,
SignInManager<ApplicationUser> signInManager,
IEmailSender emailSender,
ILogger<AccountController> logger) : base(config, userManager, signInManager, emailSender, logger)

{
_userManager = userManager;
_signInManager = signInManager;
_emailSender = emailSender;
_logger = logger;
_config = config;
}
//rest of code removed
}

更新

根据 Rufo 爵士的建议

public abstract class BaseController : Controller
{
protected UserManager<ApplicationUser> UserManager { get; }
protected SignInManager<ApplicationUser> SignInManager { get; }
protected IConfiguration Config { get; }
protected IEmailSender EmailSender { get; }
protected ILogger AppLogger { get; }

protected BaseController(IConfiguration iconfiguration,
UserManager<ApplicationUser> userManager,
SignInManager<ApplicationUser> signInManager,
IEmailSender emailSender,
ILogger<ManageController> logger)
{
AppLogger = logger;
EmailSender = emailSender;
Config = iconfiguration;
SignInManager = signInManager;
UserManager = userManager;
}
}

和继承 Controller

public class TestBaseController : BaseController
{

public TestBaseController() : base()
{

}
}

这行不通。 Resharper 告诉我必须将参数添加到 TestBaseController 构造函数中的基本构造函数调用。

在.Net Core 2.0 中,BaseController 是否应该继承自Controller 或ControllerBase?

最佳答案

Microsoft.AspNetCore.MVC.Controller类自带扩展方法

HttpContext.RequestServices.GetService<T>

只要 HttpContext 在管道中可用,就可以使用它(例如,如果从 Controller 的构造函数调用,HttpContext 属性将为 Null)

试试这个模式

注意:确保包含此指令使用 Microsoft.Extensions.DependencyInjection

基础 Controller

public abstract class BaseController<T> : Controller where T: BaseController<T>
{

private ILogger<T> _logger;

protected ILogger<T> Logger => _logger ?? (_logger = HttpContext.RequestServices.GetService<ILogger<T>>());

子 Controller

[Route("api/authors")]
public class AuthorsController : BaseController<AuthorsController>
{

public AuthorsController(IAuthorRepository authorRepository)
{
_authorRepository = authorRepository;
}

[HttpGet("LogMessage")]
public IActionResult LogMessage(string message)
{
Logger.LogInformation(message);

return Ok($"The following message has been logged: '{message}'");
}

不用说了,记得在Startup.cs中注册你的服务-->ConfingureServices方法

关于c# - .Net Core 2.0 中 Controller 和 BaseController 中的依赖注入(inject)重复,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47371513/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com