如何决定在Autofac的每个请求基础上注入哪个服务实现?

本文关键字:基础上 请求 注入 实现 服务 何决定 决定 Autofac | 更新日期: 2023-09-27 18:18:25

我正在使用ASP。. NET Web API/Autofac。是否有一种方法可以根据路由或查询字符串参数决定在每个请求的基础上注入两个可能的命名服务中的哪一个?

我的注册是这样的:

var configuration = GlobalConfiguration.Configuration;
var builder = new ContainerBuilder();
builder.RegisterApiControllers(Assembly.GetExecutingAssembly());
builder.RegisterType<Provider1>().Named<IProvider>("one").InstancePerRequest();
builder.RegisterType<Provider2>().Named<IProvider>("two").InstancePerRequest();
var container = builder.Build();
var resolver = new AutofacWebApiDependencyResolver(container);
configuration.DependencyResolver = resolver;

我的控制器:

public class SomeController : ApiController
{
    private readonly IProvider _provider;
    public SomeController(IProvider provider)
    {
        _provider = provider;
    }
    // GET /api/some?provider=x
    public IHttpActionResult Get(string provider)
    {
        //...
    }
}

如何决定在Autofac的每个请求基础上注入哪个服务实现?

可以通过注册lambda表达式来实现。

builder.Register(c => 
{
    if(true) 
    {
        return c.ResolveNamed<IProvider>("one");
    }
    else 
    {
        return c.ResolveNamed<IProvider>("two");
    }
})
.As<IProvider>()
.InstancePerRequest();

您可以进一步创建自定义接口。例如,如果希望根据站点名称注入不同的实现,则可以创建ISiteNameProvider接口。例如:

public interface ISiteNameProvider
{
    String SiteName { get; }
}
public class HttpContextSiteNameProvider : ISiteNameProvider
{
    public HttpContextSiteNameProvider(HttpContextBase context)
    {
        this._context = context;
    }
    private readonly HttpContextBase _context; 
    public String SiteName 
    {
        get 
        {
            return this._context.Request.Url.Host;
        }
    }
}
然后

builder.RegisterType<HttpContextSiteNameProvider>()
       .As<ISiteNameProvider>()
       .InstancePerRequest();
builder.Register(c => 
{
    String siteName = c.Resolve<ISiteNameProvider>().SiteName;
    if(siteName == "www.domain.com") 
    {
        return c.ResolveNamed<IProvider>("one");
    }
    else 
    {
        return c.ResolveNamed<IProvider>("two");
    }
})
.As<IProvider>()
.InstancePerRequest();
相关文章: