2013-01-19 29 views
1

我正在調整我的Web應用程序圖層以使代碼更易於測試。服務定位器模式和登錄用戶

目前UI會談傳遞一個接口的服務定位器,這將返回基於該類型適當的對象:

ServiceLocator.Get<ISomeService>().ListStuff(arg1, arg2); 

內部,服務實例化的IServiceContext和緩存的一個實例。

private static Lazy<IDictionary<Type, object>> _services = new Lazy<IDictionary<Type, object>>(GetServices); 

public interface IServiceContext 
{ 
    IConfiguration Configuration { get; } 

    IUser CurrentUser { get; internal set; } 

    ILogProvider Log { get; } 

    ICacheProvider Cache { get; } 

    IProfilerProvider Profiler { get; } 
} 

public LogService(IServiceContext serviceContext) 
    : base(serviceContext) { } 

我很高興的概念,這似乎是足夠堅固,我唯一的問題是我想要的ServiceContext登錄用戶的當前可用,但不確定實現這一目標的最佳途徑。

我的思緒沿着這些潛在的選擇旅行:

  1. 保持一個簡單的方法,在處理得到的用戶會話,並將其注入到服務作爲他們的請求進來ServiceLocator
  2. 移動獲得。當前用戶在IServiceContext之外,並進入每個服務的基類ServiceBase
  3. 停止這樣做並使每個需要用戶依賴的服務。

我明白任何建議,我明白這個問題我不是在網站的真正精神。 我已經管理了4天的試驗和錯誤到達這一點,只需要這個難題的最後一塊。

+0

不是一個服務定位的粉絲,但....我想2或3比1更好作爲解決方案。如果這是一個Web上下文並且我使用IoC,那麼我可能會通過構造函數注入'IUser',實質上就是採用#3選擇。這可能是最簡單的測試方法。 – SpaceBison

+0

我認爲你是對的。我已經檢查了實際需要這個屬性的東西,並且找出了在那裏存在的可能性以及它實際上是否需要回答這個問題之間的平衡。我想我希望有一個燈泡的時刻。 –

回答

0

可能有很多解決方案,我不完全確定我理解您的問題,但我會盡力幫助。

無論何時我需要當前用戶,我都會在使用它的代碼上下文中調用靜態實用程序類。這樣我就消除了陳舊信息的可能性。

你可以做一個實現IUser

class User : IUser { 
    private System.Security.Principal.WindowsIdentity identity; 

    public User() { 
    this.identity = identity = System.Security.Principal.WindowsIdentity.GetCurrent(); 
    } 

    public string UserName { get { return this.identity.Name; } } 
} 

,然後也許一個類:

public class ServiceContext : IServiceContext 
{ 
    IUser CurrentUser { get { return new User(); } } 
} 
+0

這就是我所擁有的,但是我只是重構了很多代碼,以避免使用效用方法,因爲它們阻礙了測試。感謝您的時間和建議。 –