2014-02-14 202 views
13

簡單注射器是否允許您在解析時將參數傳遞給構造函數?我想知道這兩個框架是否執行Unity的ResolverOverride或DependencyOverride。如何使用Simple Injector將參數傳遞給構造函數?

+2

我認爲最好將問題分成兩個單獨的問題(每個框架一個)。這讓您更容易接受一個正確的答案,並且使其他人能夠更輕鬆地在相關容器中對此進行谷歌搜索。 – Steven

回答

14

我懷疑,這個問題是關於傳遞原始值構造函數當時服務實際上已經解決了。

讓我們建立一個簡單的測試類:

public interface IFoo 
{ 

} 

public class Foo : IFoo 
{ 
    public Foo(string value) 
    { 

    } 
} 

Foo類需要我們想解決的IFoo服務時提供一個字符串參數。

var container = new ServiceContainer(); 
container.Register<string, IFoo>((factory, value) => new Foo(value)); 
var firstFoo = container.GetInstance<string, IFoo>("SomeValue"); 
var secondFoo = container.GetInstance<string, IFoo>("AnotherValue"); 

如果我們希望能夠不直接使用的容器來創建Foo類的新實例,我們可以簡單地注入功能委託。

public interface IBar { } 

public class Bar : IBar 
{ 
    public Bar(Func<string, IFoo> fooFactory) 
    { 
     var firstFoo = fooFactory("SomeValue"); 
     var secondFoo = fooFactory("AnotherValue"); 
    } 
} 

的「成分根」現在看起來是這樣的:

var container = new ServiceContainer(); 
container.Register<string, IFoo>((factory, value) => new Foo(value)); 
container.Register<IBar, Bar>(); 
var bar = container.GetInstance<IBar>(); 

如果問題是關於通過一個「靜態」的原始值的構造器,這是通過簡單地註冊一個工廠委託像做這個。

var container = new ServiceContainer(); 
container.Register<IFoo>((factory) => new Foo("SomeValue")); 
var firstInstance = container.GetInstance<IFoo>(); 
var secondInstance = container.GetInstance<IFoo>(); 

不同之處在於,此方法不允許您在解析時傳遞值。該值在註冊時間靜態指定。

+7

一切都很好。我只是不喜歡該行 container.Register ((factory,value)=> new Foo(value)); 如果Foo具有其他一些依賴關係IService1,...,IServiceN應該由容器注入什麼呢?我只想說,只使用特定的字符串作爲特定參數,其餘參數容器應提供依賴關係。我如何才能做到這一點? – user1325696

+1

'container.Register ((factory)=> new Foo(container.GetInstance (),「SomeValue」));'? – Marcello

+2

請問我們可以停止使用「foo」和「bar」嗎? –

10

可能與Simple Injector最簡單的方法是用委託註冊

[Test] 
public void Test1() 
{ 
    Container container = new Container(); 

    container.Register<IClassWithParameter>(() => new ClassWithParameter("SomeValue")); 

    var result = container.GetInstance<IClassWithParameter>(); 
} 

public interface IClassWithParameter { } 

public class ClassWithParameter : IClassWithParameter 
{ 
    public ClassWithParameter(string parameter) 
    { 
    } 
} 

注入原始的依賴關係的高級選項是詳細here

2

如果您的構造函數沒有任何其他依賴關係(或者您想手動解決這些依賴關係),上述方法將全部有效。如果你有以下情況,雖然它倒下:

public class Test : ITest 
{ 
    private IFoo _foo; 
    public Test(string parameter, IFoo foo) 
    { 
     _foo = foo; 
     .... 
    } 
} 

現在,你不僅要手動進繩子,但也Foo。所以現在你根本不使用依賴注入(真的)。還有簡單注射器狀態:

簡單注射器不允許將基元類型(如 整數和字符串)注入構造函數。

所以他們有點說不要這樣做。

這裏的另一個選擇是使用"Extensibillity points" for this scenario

要做到這一點,你需要抽象你硬編碼元素從注入的元素:

public class Test : ITest 
{ 
    private IFoo _foo; 
    public Test(IFoo foo) 
    { 
     _foo = foo; 
     .... 
    } 

    public void Init(string parameter) 
    { 

    } 
} 

您現在可以注入你的dependanices 您的硬編碼元素:

_container.Register<ITest, Test>(); 
_container.RegisterInitializer<Test>(instance => {instance.Init("MyValue");}); 

如果你現在添加另一個依賴,您的注射現在將工作,無需您更新配置:

public class Test : ITest 
{ 
    private IFoo _foo; 
    private IBar _bar; 
    public Test(IFoo foo, IBar bar) 
    { 
     _foo = foo; 
     _bar = bar; 
     .... 
    } 

    public void Init(string parameter) 
    { 

    } 
} 
相關問題