Simple Injector允许您在解析时将参数传递给构造函数吗?我想知道这两个框架是否都可以执行Unity的ResolverOverride或DependencyOverride。
答案 0 :(得分:22)
我怀疑这个问题是关于在实际解析服务时将原始值传递给构造函数。
让我们设置一个简单的测试类:
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>();
不同之处在于此方法不允许您在解决时传递值。该值在注册时静态指定。
答案 1 :(得分:18)
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 :(得分:3)
如果您的构造函数没有任何其他依赖项(或者您希望手动解析这些依赖项),则上述操作都可以正常工作。如果你有下面的情况虽然它下降了:
public class Test : ITest
{
private IFoo _foo;
public Test(string parameter, IFoo foo)
{
_foo = foo;
....
}
}
现在,您不仅需要手动注入字符串,还需要Foo
。所以现在你根本没有使用依赖注入(真的)。也是简单的注射器状态:
Simple Injector不允许注入原始类型(例如 整数和字符串)到构造函数。
我对此的解读是,他们说'不要这样做&#34;。
此处的另一个选择是使用"Extensibillity points" for this scenario。
为此,您需要从注入的元素中抽象出硬编码元素:
public class Test : ITest
{
private IFoo _foo;
public Test(IFoo foo)
{
_foo = foo;
....
}
public void Init(string parameter)
{
}
}
您现在可以注入您的依赖项和您的硬编码元素:
_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)
{
}
}
答案 3 :(得分:1)
针对利亚姆的回答,我想指出,有一种更简单的方法。
如果您遇到以下情况:
public class Test : ITest
{
private IFoo _foo;
public Test(IFoo foo, string parameter)
{
_foo = foo;
....
}
}
您可以按如下方式编写ioc配置
_container.Register<IFoo, Foo>();
_container.Register<ITest>(
() => new Test(
_container.GetInstance<IFoo>(),
"MyValue"
)
);