假设我有一个课程如下
public class Foo
{
public Foo(string someTitle, IFooService fooService)
{
// do stuff
}
}
我知道我可以使用DI和autofac
来实例化它public class Bar
{
public Bar(Func < string, IFooService, Foo > foo, IFooService fooService)
{
var foo = foo("some string", fooService);
}
}
但我想知道Bar
是否有任何方法可以不了解IFooService
的任何内容?我不想为了满足func而将IFooService注入Bar。
基本上是这样的
// pseudo code - don't use
public class Bar
{
public Bar(Func < string, Foo > foo)
{
var foo = foo("some string");
}
}
我在我的应用中真正想做的是删除所有服务位置实例,并完全依赖依赖注入。
答案 0 :(得分:5)
Autofac应该能够使用the Func<T>
implicit relationship完全按照您的意愿完成。
这是一个小型repro,显示如何省略IFooService
中的Func<T>
参数,只要其他依赖项可以通过Autofac解决,您就可以了。< / p>
做一些疯狂工作的样本类型......
public class Bar
{
private Foo _foo;
// This constructor looks like what you're aiming for...
public Bar(Func<string, Foo> factory)
{
this._foo = factory("title");
}
public void ShowMeCoolStuff()
{
this._foo.DoWork();
}
}
public class Foo
{
private string _title;
private IFooService _service;
// The Foo class takes the title AND an IFooService...
public Foo(string title, IFooService service)
{
this._title = title;
this._service = service;
}
public void DoWork()
{
Console.WriteLine("Foo title = {0}", this._title);
this._service.DoMoreWork();
}
}
public interface IFooService
{
void DoMoreWork();
}
public class FooService : IFooService
{
public void DoMoreWork()
{
Console.WriteLine("FooService doing more work.");
}
}
注册时,请确保所有依赖项都已注册 - Foo
,Bar
,正在实施IFooService
:
var builder = new ContainerBuilder();
builder.RegisterType<Foo>();
builder.RegisterType<Bar>();
builder.RegisterType<FooService>().As<IFooService>();
var container = builder.Build();
当你解决时,一切都紧紧抓住了。这个决议......
var bar = container.Resolve<Bar>();
bar.ShowMeCoolStuff();
...将产生以下控制台输出:
Foo title = title
FooService doing more work.
There is fairly robust documentation with examples over on the Autofac site.
答案 1 :(得分:2)
您使用工厂的地方:
public interface IFooFactory
{
Foo CreateFoo(string value);
}
栏可以简单地依赖IFooFactory
。
实施可以如下所示:
public class FooFactory : IFooFactory
{
private readonly IFooService fooService;
public FooFactory(IFooService fooService)
{
this.fooService = fooService;
}
public Foo CreateFoo(string value)
{
return new Foo(value, this.fooService);
}
}
但是给定的字符串看起来像是运行时值,即从请求到请求或从调用到调用的值。根据解释here,here和here,防止将运行时值与设计时依赖性混合在一起。而是将运行时值作为方法参数传递给您调用的Foo
方法。这将彻底解决问题。