Autofac - 注册以接口为参数的实例类型

时间:2017-07-20 06:29:01

标签: api dependency-injection autofac ioc-container

我是Autofac的新手,无法理解注册的语法。我有以下calsses / interfaces:

//Interface
public interface ISender
{
    void Send();
}


//implementations 
public class Post : ISender
{
    public void Send()
    {
        //Post implementation
    }
}

public class Email : ISender
{
    public void Send()
    {
        //Email implementation
    }
}  

一个调用这些实现的类

public class Consumer
{
    ISender Sender;

    public Consumer(ISender sender)
    {
        Sender = sender
    }

    public void Act()
    {
        Sender.Send();
    }   
}

现在,要在控制器中决定调用哪个实现,所以我尝试使用this page中的IIndex:

public calss PostController
{
    Consumer ConsumerObject;
    public PostController(IIndex<string, Consumer> consumer)
    {
        ConsumerObject = consumer["post"];
    }

}

public class EmailController
{
    Consumer ConsumerObject;
    public PostController(IIndex<string, Consumer> consumer)
    {
        ConsumerObject = consumer["email"];
    }
}

首先,它是正确的还是可行的?现在问题是我不懂如何在Autofac中注册。那么,我们如何在Autofac中注册Consumer和ISender?请建议是否有更好/替代方式。

1 个答案:

答案 0 :(得分:0)

在Autofac中注册组件的方式在文档here中有详细描述。您链接的文档中描述了如何使用键控服务。

基本上,您必须创建ContainerBuilder,根据您拥有的项目类型注册所有组件并构建容器本身。

在您的情况下,您需要使用以下注册:

var builder = new ContainerBuilder();
builder.RegisterType<Post>().Keyed<ISender>("post");
builder.RegisterType<Email>().Keyed<ISender>("email");
builder.RegisterType<Consumer>();

如果您使用ASP.NET WebApi(我假设您基于使用控制器的事实),则需要注册控制器

builder.RegisterApiControllers(Assembly.GetExecutingAssembly());

或MVC

builder.RegisterControllers(typeof(MvcApplication).Assembly);

现在,有各种方法可以选择Consumer并使用正确的ISender实现(我假设你想在控制器中选择适当的实现)。

一种方法是将IIndex<string, ISender>注入Consumer类,并将正确的密钥字符串传递给它:

public class Consumer
{
    ISender Sender;

    public Consumer(string type, IIndex<string, ISender> sender)
    {
        Sender = sender[type];
    }

    public void Act()
    {
        Sender.Send();
    }   
}

然后,在控制器中,您可以使用Func注入:

public class PostController
{
    Consumer ConsumerObject;
    public PostController(Func<string, Consumer> consumer)
    {
        ConsumerObject = consumer("post");
    }
}

public class EmailController
{
    Consumer ConsumerObject;
    public EmailController(Func<string, Consumer> consumer)
    {
        ConsumerObject = consumer("email");
    }
}

另一个可能是使用Register方法两次注册消费者并在注册时间内解析ISender

相关问题