2014-02-14 148 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) 
    { 

    } 
} 
相关问题