[英]Creating volatile interfaces instances - dependency injection vs service locator
問題是我有3層項目: DataAccess
dll和Presentation
dll取決於Logic
dll。 在邏輯上,我定義了IRepository, IMyIdentityUser
等接口。在DataAccess中,我使用Microsoft Identity框架向繼承了IdentityUser<Guid>
和IMyIdentityUser
接口的MyIdentityUser注冊新用戶。 我也在使用IoC容器。 假設我在Presentation(MVC)層中有一個名為' Register
'的方法,其參數為' RegisterViewModel viewModel
',該方法將注冊邏輯委托給Logic
dll中的某個類。
public async Task<ActionResult> Register(RegisterViewModel model)
{
if (ModelState.IsValid)
{
var user = MyCore.Resolve<IMyIdentityUser>(); //this is service locator
// antipattern and I want to get
// rid of this
user.UserName = model.Email;
user.Email = model.Email;
var userManager = _userManager;
var result = await userManager.CreateAsync(user, model.Password);
if (result.Succeeded)
{
var signInManager = _signInManager;
await signInManager.SignInAsync(user, false, false);
return RedirectToAction("Index", "Home");
}
AddErrors(result);
}
return View(model);
}
如您所見,我正在使用服務定位器來獲取MyIdentityUser的新實例。 我不想將其創建為“ new MyIdentityUser()
”,因為這迫使我與定義MyIdentityUser的DataAccess dll緊密耦合。 另外,我不想每次創建MVC控制器時都在構造函數參數IMyIdentityUser
強制使用IoC容器來創建新的用戶實例。 我想我可以使用某種抽象工廠
interface IMyIdentityUserFactory
{
IMyIdentityUser CreateNewUser(string name, string email); //any other better arguments?
// not like registerViewModel because
// this view model should be defined in presentation logic
}
並將其作為參數傳遞給控制器構造函數(也許在帶有另一個邏輯連接參數的Facade參數中),但是我不確定,因為它通常與傳遞孤獨的IMyIdentityUser
相同。 有更好的方法嗎?
另外,我不希望每次創建MVC控制器時都在構造函數參數IMyIdentityUser中強制IoC容器創建新的用戶實例。
您的前提是從頭開始是錯誤的。
IControllerActivator
則可以更改此默認行為!) 因此,基於您的錯誤假設,無論何時需要依賴項,我都會明確采用構造函數注入。 還是屬性注入 ,但這不是實現依賴項注入的首選,因為通常屬性注入是可選的 。
另一方面,構造注入應該是可行的方法,因為在可測試性方面,每段代碼都將彼此獨立(較少耦合):您可以自動或手動實例化給定的類,還可以自動或手動提供其依賴項。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.