繁体   English   中英

创建易失性接口实例-依赖注入与服务定位器

[英]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容器创建新的用户实例。

您的前提是从头开始是错误的。

  1. MVC控制器不是有状态的。 每个请求都实例化一个MVC控制器(好吧,如果您在此处阅读了第二点,您可能会争辩说,如果实现IControllerActivator则可以更改此默认行为!)
  2. IoC容器不一定会创建给定注入依赖性的新实例:它取决于组件的生命周期。 例如,Castle Windsor将为您提供瞬态,单例,按请求,按线程,池化和其他生命周期。 瞬态将是肯定会创建给定注入依赖项实例的唯一选择。

因此,基于您的错误假设,无论何时需要依赖项,我都会明确采用构造函数注入。 还是属性注入 ,但这不是实现依赖项注入的首选,因为通常属性注入是可选的

另一方面,构造注入应该是可行的方法,因为在可测试性方面,每段代码都将彼此独立(较少耦合):您可以自动或手动实例化给定的类,还可以自动或手动提供其依赖项。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM