Sea*_*ron 11 .net c# dependency-injection ioc-container funq
Funq IoC容器是否支持解析类型的所有注册?像这两个中的任何一个:
IEnumerable<IFoo> foos = container.Resolve<IEnumerable<IFoo>>();
IEnumerable<IFoo> foos = container.ResolveAll<IFoo>();
Run Code Online (Sandbox Code Playgroud)
Funq没有ResolveAll方法,但您只需注册IEnumerable<IFoo>并Resolve<IEnumerable<IFoo>>()在问题中显示就可以解决问题.
但是,一般情况下,最好不要为容器请求容器,而是使用复合材料.这样,您可以简单地将一个IFoo作为依赖项注入,而不是强制该依赖项的使用者迭代该列表.相反,您嵌入了IFoo在复合内部循环实例列表的代码.这样可以使您的代码保持干燥状态,并且不会强制您浏览foreach (var foo in foos)分散在整个应用程序中的(可能的)几十个语句,这时必须按照项目的迭代方式进行更改.或者让我以另一种方式表达它:消费者不负责知道如何迭代所有IFoos.
以下是IFooComposite 的示例:
// A composite is something that implements an interface
// (in this case IFoo) and wraps a list of items of that
// same interface.
public class FooComposite : IFoo
{
private readonly IEnumerable<IFoo> foos;
public FooComposite(params IFoo[] foos)
{
this.foos = foos;
}
void IFoo.FooThatThing(IBar bar)
{
foreach (var foo in this.foos)
{
foo.FooThatThing(bar);
}
}
}
Run Code Online (Sandbox Code Playgroud)
而不是注册一个的IEnumerable<IFoo>,你可以注册CompositeFoo为IFoo:
container.Register<IFoo>(c => new CompositeFoo(
new Foo1(), new Foo2(), new Foo3()));
Run Code Online (Sandbox Code Playgroud)
现在你可以让容器CompositeFoo在带有IFoo参数的消费者中注入,这使得他们不知道他们实际上在处理IFoo元素列表.
更新:
使用此复合模式,您可以轻松控制每个IFoo项目的生命周期.这只是回调容器的问题.使用Funq,它看起来像这样:
container.Register<IFoo>(c => new CompositeFoo(
c.Resolve<Foo1>(),
c.Resolve<Foo2>(),
c.Resolve<Foo3>()));
Run Code Online (Sandbox Code Playgroud)
这样,您可以注册Foo1为单例和Foo2例如瞬态.CompositeFoo然而,当重用时,Foo2不会真正是短暂的,但它只是改变它CompositeFoo和它的注册来解决这个问题.例如,您可以将您更改CompositeFoo为以下内容:
public class FooComposite : IFoo
{
private readonly Func<IFoo>[] fooFactories;
public FooComposite(params Func<IFoo>[] fooFactories)
{
this.fooFactories = fooFactories;
}
void IFoo.FooThatThing(IBar bar)
{
foreach (var fooFactory in this.fooFactories)
{
var foo = fooFactory();
foo.FooThatThing(bar);
}
}
}
Run Code Online (Sandbox Code Playgroud)
现在IFoo我们可以在构造函数中注入一些lambda 而不是注入一些s:
container.Register<IFoo>(c => new CompositeFoo(
() => c.Resolve<Foo1>(),
() => c.Resolve<Foo2>(),
() => c.Resolve<Foo3>()));
Run Code Online (Sandbox Code Playgroud)
这将确保每一次CompositeFoo的FooThatThing被调用时,容器中查询新的IFoo实例.这允许FooThatThing由同一消费者多次调用,甚至允许CompositeFoo注册为单身.
这个建议一般适用于所有容器和依赖注入,并不特定于Funq的使用.