2016-09-30 43 views
0

问题是我有3层项目:DataAccess DLL和Presentation DLL取决于Logic DLL。在逻辑中,我定义了接口od IRepository, IMyIdentityUser等。在DataAccess中,我使用Microsoft Identity Framework向MyIdentityUser注册新用户,该用户继承IdentityUser<Guid>IMyIdentityUser接口。我也在使用IoC容器。 假设我在演示文稿(MVC)图层方法名为'Register',参数'RegisterViewModel viewModel'正在将注册逻辑委托给Logic dll中的某个类。创建易失性接口实例 - 依赖注入vs服务定位器

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紧密耦合。 另外,我不想在构造函数参数IMyIdentityUser中强制每次创建MVC控制器时强制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 
} 

,并把它当作参数传递给控制器​​的构造函数(也许在另一个逻辑连接参数门面参数),但我不知道这一点,因为这是一般与寂寞传递IMyIdentityUser一样。 有没有更好的方法来做到这一点?

回答

3

而且,我不想在构造函数的参数IMyIdentityUser和 迫使IoC容器每一次我 创建MVC控制器创建新的用户实例。

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

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

因此,基于你错误的假设,我会明确地去与构造函数注入无论你需要依赖。或属性注入,但它不是实施依赖注入时的首选,因为通常属性注入是可选。另一方面,构建注入应该是一条路,因为每一段代码在可测试性方面都将独立于其他(较少耦合):您可以自动或手动实例化给定类,也可以自动或手动实例化提供它的依赖关系。

+0

A.D. 1. 是的,它们不是有状态的。因此,如果控制器有4个方法,并且只有其中一个需要来自构造函数的新用户,则每次我们使用剩余的3个方法时,让IoC容器创建此用户会浪费资源 - 假定用户具有瞬态或每个请求的生命周期。但它不能是单身或者每个线程,并且集中也没有多大意义。最好为Register方法创建此用户**。 当然,新用户是非常轻的对象,不会影响应用程序的性能,但我仍然想知道如何正确执行此操作。 –

+0

@BartekWójcik我会在更新中回答你! –

+0

@BartekWójcik那么让我们在这里讨论这个之前,我的答案添加更新.... –