2010-04-12 49 views
1

爲什麼Microsoft.Practices.ServiceLocation.IServiceLocator不提供TryGetInstance()?Microsoft.Practices.ServiceLocation和TryGetInstance

我需要獲得通用驗證器實例ServiceLocator.Current.GetInstance<IEntityValidator<TEntity>>()但並非所有實體都已註冊驗證器。

我發現的唯一解決方案是使用try {} catch {}塊,但我不喜歡這種方法。

回答

4

我不能告訴你爲什麼這個方法不存在,但我想提供opion是因爲你不應該在一個拉基於使用DI容器它不應該的問題無論如何。這是Service Locator anti-pattern

如果你需要一個IEntityValidator<Foo>,然後通過構造要求依賴性:

public class Foo 
{ 
    private readonly IEntityValidator<Foo> validator; 

    public Foo(IEntityValidator<Foo> validator) 
    { 
     this.validator = validator; 
    } 
} 

您可以處理,並非所有的實體以不同方式註冊驗證程序的問題。

我的首選方法是爲所有這些實體註冊Null Validator

或者,你可以給你的實體一個構造函數重載,不會帶一個驗證器,然後從該構造函數中分配一個Null驗證器。這可能看起來像這樣:

public class Foo 
{ 
    private readonly IEntityValidator<Foo> validator; 

    public Foo() 
    { 
     this.validator = new NullValidator<Foo>(); 
    } 

    public Foo(IEntityValidator<Foo> validator) 
    { 
     this.validator = validator; 
    } 
} 

但是,無論是否工作或部分取決於您的特定DI容器。作爲一個例子,Castle Windsor使用最貪婪的構造函數它可以滿足,所以在那種情況下,即使驗證器沒有註冊,它也能工作,因爲它只會選擇默認的構造函數。

在任何情況下,基於推式的方法是真正依賴注入。採用這種方法,您可以使用DI容器至resolve the entire dependency graph in one go at the application's entry point

3

CSL不支持的原因是並非所有的IoC框架都支持這種機制。 Common Service Locator討論論壇爲此問題提供了一種解決方法。 Read this question

我同意馬克,你應該嘗試註冊一個空對象是你可以並在可能時堅持真正的依賴注入。