공통 종속성 중 일부를 캡슐화하는 Asp.Net Core 2.0 웹 응용 프로그램에서 BaseController를 만들면 여전히 실제 컨트롤러에 필요합니다..Net Core 2.0의 컨트롤러 및 BaseController에서 의존성 주입 복제
예를 들어 기본 MVC 6 웹 응용 프로그램의 표준 계정 및 관리 컨트롤러. 내가 구축하고 사용자 지정 웹 응용 프로그램 템플릿 나는 세 가지 다른 컨트롤러에 계정 컨트롤러를 리팩토링에서
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
}
(사용자 등록에 관한 모든 것을 처리) RegisterController (로그인과 로그 아웃을 처리) 인 LoginController 및 균형에 세번째. 나는 Manage 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
}
하지만 아무 것도 달성하지 못한 것 같습니다. 왜냐하면 나에게 보이는 것처럼 나는 모든 것을 주입해야한다. 내가 옳을 수는 없다. (나는 DI에 대해 전혀 새로운 단서가 없다.) 그러나 BaseController는 BaseController와 RegisterController 사이에 공통적 인 DI를 허용하지 않아야한다. 내가 잘못? 내가하려는 일을 어떻게 성취합니까?
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;
}
}
당
그리고이 작동하지 않습니다 상속 컨트롤러
public class TestBaseController : BaseController
{
public TestBaseController() : base()
{
}
}
. Resharper는 TestBaseController 생성자에서 기본 생성자 호출에 매개 변수를 추가해야한다고 말합니다.
또한 BaseController는 .Net Core 2.0의 Controller 또는 ControllerBase에서 상속해야합니까?
'BaseController'가 생성자 호출에서 그것들 모두를 제공해야한다면, 그렇다. 하지만 당신은'BaseController'를 리펙토링하여 이들 모두를 필요로하지 않을 수 있습니다. 또한,'BaseController'와 그것의 하위 클래스 모두에서 참조를 저장하는 이유는 무엇입니까? – fredrik
@ fredrik .. 내가 게시물에서 언급 한 5 명의 컨트롤러는 모두 DI가 필요합니다. 실제 컨트롤러에서해야 할 일은 모두 있습니까? 개인 참조를 제거하고 전달 된 매개 변수를 사용하십시오. 즉, _signInManager.IsSignedIn 대신 signInManager.IssignedIn? – dinotom
BaseController의 보호 된 속성을 통해 삽입 된 참조를 게시하여 파생 클래스에서 액세스 할 수 있습니다. –