[英]Creating volatile interfaces instances - dependency injection vs service locator
The problem is i have 3 layer project: DataAccess
dll and Presentation
dll depends on Logic
dll. 问题是我有3层项目:
DataAccess
dll和Presentation
dll取决于Logic
dll。 In logic i have defined interfaces od IRepository, IMyIdentityUser
etc. In DataAccess I'm using Microsoft Identity framework to registering new users with MyIdentityUser that inherits IdentityUser<Guid>
and IMyIdentityUser
interface. 在逻辑上,我定义了
IRepository, IMyIdentityUser
等接口。在DataAccess中,我使用Microsoft Identity框架向继承了IdentityUser<Guid>
和IMyIdentityUser
接口的MyIdentityUser注册新用户。 I am also using IoC container. 我也在使用IoC容器。 Let's say I have in Presentation (MVC) layer method called '
Register
' with argument ' RegisterViewModel viewModel
' that is delegating registering logic to some class in Logic
dll. 假设我在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);
}
as you see I'm using Service locator to get new instance of MyIdentityUser. 如您所见,我正在使用服务定位器来获取MyIdentityUser的新实例。 I don't want to create this as '
new MyIdentityUser()
' because this forces me use tight coupling with DataAccess dll where MyIdentityUser is defined. 我不想将其创建为“
new MyIdentityUser()
”,因为这迫使我与定义MyIdentityUser的DataAccess dll紧密耦合。 Also, I don't want to have in constructor parameter IMyIdentityUser
and forcing IoC container to create new user instance each time I'm creating MVC controller. 另外,我不想每次创建MVC控制器时都在构造函数参数
IMyIdentityUser
强制使用IoC容器来创建新的用户实例。 I think I could use some kind of abstract factory like 我想我可以使用某种抽象工厂
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
}
and passing it as argument to controller constructor (maybe in facade parameter with another logically connected parameters) but I'm not sure of this because it's generally the same as passing lonely IMyIdentityUser
. 并将其作为参数传递给控制器构造函数(也许在带有另一个逻辑连接参数的Facade参数中),但是我不确定,因为它通常与传递孤独的
IMyIdentityUser
相同。 Is there better way to do this? 有更好的方法吗?
Also, i dont want to have in constructor parameter IMyIdentityUser and forcing IoC container to create new user instance each time i'm creating MVC controller.
另外,我不希望每次创建MVC控制器时都在构造函数参数IMyIdentityUser中强制IoC容器创建新的用户实例。
Your premise is wrong from scratch. 您的前提是从头开始是错误的。
IControllerActivator
!) IControllerActivator
则可以更改此默认行为!) Thus, based on your wrong assumptions, I would definitively go with constructor injection wherever you need a dependency. 因此,基于您的错误假设,无论何时需要依赖项,我都会明确采用构造函数注入。 Or property injection , but it's not the first choice when implementing dependency injection, because usually property injections are optional .
还是属性注入 ,但这不是实现依赖项注入的首选,因为通常属性注入是可选的 。
In the other hand, construction injection should be the way to go because every piece of code will be independent of others (less coupling) in terms of testability: you can automatically or manually instantiate a given class and also automatically or manually provide its dependencies. 另一方面,构造注入应该是可行的方法,因为在可测试性方面,每段代码都将彼此独立(较少耦合):您可以自动或手动实例化给定的类,还可以自动或手动提供其依赖项。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.