使用Func和依赖注入的Autofac动态调用

Cha*_*ell 1 c# dependency-injection autofac service-locator

假设我有一个课程如下

public class Foo
{
    public Foo(string someTitle, IFooService fooService)
    { 
        // do stuff
    }
}
Run Code Online (Sandbox Code Playgroud)

我知道我可以使用DI和autofac这样实例化它

public class Bar
{
    public Bar(Func < string, IFooService, Foo > foo, IFooService fooService)
    {
        var foo = foo("some string", fooService);
    }
}
Run Code Online (Sandbox Code Playgroud)

但我想知道是否有任何方法Bar可以不知道任何事情IFooService?我不想为了满足func而将IFooService注入Bar.

基本上是这样的

// pseudo code - don't use
public class Bar
{
    public Bar(Func < string, Foo > foo)
    {
        var foo = foo("some string");
    }
}
Run Code Online (Sandbox Code Playgroud)

我在我的应用程序中真正想做的是删除所有服务位置实例,并完全依赖依赖注入.

Tra*_*lig 5

Autofac应该能够做的正是你使用想要什么Func<T>隐含关系.

这是一个小的repro,展示了如何省略IFooService参数,Func<T>只要其他依赖关系可以通过Autofac解决,你就可以了.

做一些疯狂工作的样本类型......

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.");
    }
}
Run Code Online (Sandbox Code Playgroud)

注册时,请确保所有依赖项都已注册 - Foo,Bar实现的内容IFooService:

var builder = new ContainerBuilder();
builder.RegisterType<Foo>();
builder.RegisterType<Bar>();
builder.RegisterType<FooService>().As<IFooService>();
var container = builder.Build();
Run Code Online (Sandbox Code Playgroud)

当你解决时,一切都在排队.这个决议......

var bar = container.Resolve<Bar>();
bar.ShowMeCoolStuff();
Run Code Online (Sandbox Code Playgroud)

...将产生以下控制台输出:

Foo title = title
FooService doing more work.
Run Code Online (Sandbox Code Playgroud)

在Autofac网站上有相当强大的文档和示例.