共通の依存関係の一部をカプセル化するAsp.Net Core 2.0 WebアプリケーションでBaseControllerを作成しても、それは実際のコントローラーではまだ必要です。.Net Core 2.0のコントローラーとBaseControllerの依存性注入の重複
例えば、デフォルトのMVC 6 Webアプリケーションの標準のアカウントと管理コントローラ。私は、私は、3つの異なるコントローラにアカウントコントローラをリファクタリング構築(ユーザー登録に関するすべてを扱う)RegisterController、(ログインとログアウトを扱う)LoginController、そしてバランスにしていますカスタムWebアプリケーションテンプレートで
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
}
三分の一。 Manage Controllerを2つに分割し、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'にコンストラクタ呼び出しのすべてを提供する必要がある場合は、yesを返します。しかし、それらのすべてを必要としないように 'BaseController'をリファクタリングすることができます。また、 'BaseController'とそのサブクラスの両方で参照を保存する理由は? – fredrik
@ fredrik ..私がポストで言及している5つのコントローラは、すべてそれらのDIが必要です。それは私が実際のコントローラで行う必要があるのでしょうか?プライベート参照を削除し、渡されたパラメータを使用するだけですか?つまり、_signInManager.IsSignedInではなく、signInManager.IssignedIn? – dinotom
注入された参照をBaseControllerの保護されたプロパティを介してパブリッシュして、派生クラスからアクセスできるようにします –