2016-09-30 41 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那麼讓我們在這裏討論這個之前,我的答案添加更新.... –