使用Autofac在两个控制器中获取不同的界面

时间:2016-07-07 03:26:48

标签: c# asp.net-mvc autofac

我想在不同的控制器中使用不同的接口。

public interface IMessenger {
    Id {get; set;}
    void Send();
}

我有两个类实现两个相同的接口。

public class SmsSender : IMessenger {
    public Id {get; set;}
    public void Send() {
         //logic here
    }    
}

public class MailSender : IMessenger {
    public Id {get; set;}
    public void Send() {
         //logic here
    }    
}

两个控制器:

public class HomeController : Controller {

    private readonly IMessenger _messenger;

    public HomeController(IMessenger messenger) {
        _messenger = messenger;
    }
}


public class Home2Controller : Controller {

    private readonly IMessenger _messenger;

    public HomeController(IMessenger messenger) {
        _messenger = messenger;
    }
}

Autofaq设置:

builder.RegisterType<MailSender>().As<IMessenger>().InstancePerLifetimeScope();

builder.RegisterType<SmsSender>().As<IMessenger>().InstancePerLifetimeScope();

如何在HomeController中获取 SmsSender ,在Home2Controller中获取 MailSender

2 个答案:

答案 0 :(得分:3)

注册组件时,您可以使用WithParameter方法告诉 Autofac 选择哪个依赖项。

builder.RegisterType<Service>()
       .As<IService>()
       .WithParameter((pi, c) => pi.ParameterType == typeof(IDependency),
                      (pi, c) => new XDependency());

为了避免使用new XDependency代码并让 Autofac 创建依赖项,您可以解析命名注册。

builder.RegisterType<XDependency>().Named<IDependency>("X");
builder.RegisterType<YDependency>().Named<IDependency>("Y");

并使用c.ResolveNamed<IDependency>("X")

解决此问题

另一个解决方案是让组件使用IIndex<TKey, TService>选择它想要的依赖项。要使用此功能,您必须将IDependency注册为命名注册并注入IIndex<String, IDependency>

public class Service 
{
    public Service(IIndex<String, IDependency> dependencies)
    {
        this._dependency = dependencies["X"]; 
    }

    private readonly IDependency _dependency;
}

有关详细信息,请查看 autofac 文档中的常见问题解答:How do I pick a service implementation by context

答案 1 :(得分:0)

你做不到。 Autofac无法找出差异。最好将它们分成两个不同的接口,将您需要的接口注入控制器。从设计的角度来看,依赖性也更清晰。如果有需要,两个接口都可以实现IMessenger。