You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ASP.NET Core 2.0中Autofac上下文绑定失效问题求助

Autofac Contextual Binding Not Working in ASP.NET Core 2.0

I’ve run into this exact issue when migrating from ASP.NET MVC 5/Web API 2 to Core 2.0—let’s break down why your configuration isn’t working and how to fix it.

Why Your Current Setup Fails

There are two critical issues here:

  1. ASP.NET Core’s Default Controller Activation: Unlike older ASP.NET frameworks, Core 2.0 doesn’t use the DI container to activate controllers by default. It creates controllers directly, so your WithParameter configurations on controller registrations are completely ignored. All ISender dependencies pull the default DefaultSender because that’s what the container resolves when the framework requests a plain ISender.

  2. Syntax Error in Registration: Look closely at your CustomersController code—there’s an extra semicolon after builder.RegisterType<CustomersController>();, which breaks the method chain. The WithParameter call never attaches to the controller registration, so it never takes effect.

Fixes to Get Contextual Binding Working

Step 1: Let Autofac Take Over Controller Activation

First, tell ASP.NET Core to use the DI container for controller activation. In your Startup.cs ConfigureServices method, add .AddControllersAsServices() to your MVC setup:

public IServiceProvider ConfigureServices(IServiceCollection services)
{
    // Enable controller activation via DI
    services.AddMvc().AddControllersAsServices();

    var builder = new ContainerBuilder();
    // Import Core services into Autofac
    builder.Populate(services);

    // Your service registrations go here...
}

Step 2: Fix the Syntax Error

Remove the extra semicolon in your CustomersController registration:

// Before (broken)
builder.RegisterType<CustomersController>();
.WithParameter(...)

// After (fixed)
builder.RegisterType<CustomersController>()
.WithParameter(
    new ResolvedParameter(
        (pi, ctx) => pi.ParameterType == typeof(ISender),
        (pi, ctx) => ctx.Resolve<EmailNotifier>()))
.InstancePerLifetimeScope();

While fixing the above may get your original setup working, using keyed services is a cleaner, more maintainable approach for contextual binding in Autofac:

Register ISender Implementations as Keyed Services

builder.RegisterType<PostalServiceSender>()
       .Keyed<ISender>("shipping-strategy")
       .InstancePerLifetimeScope();

builder.RegisterType<EmailNotifier>()
       .Keyed<ISender>("notification-strategy")
       .InstancePerLifetimeScope();

// Keep the default ISender registration
builder.RegisterType<DefaultSender>()
       .As<ISender>()
       .InstancePerLifetimeScope();

Bind Keyed Services to Controllers

You can either use WithParameter with a keyed resolved parameter:

builder.RegisterType<ShippingController>()
       .WithParameter(ResolvedParameter.ForKeyed<ISender>("shipping-strategy"))
       .InstancePerLifetimeScope();

builder.RegisterType<CustomersController>()
       .WithParameter(ResolvedParameter.ForKeyed<ISender>("notification-strategy"))
       .InstancePerLifetimeScope();

Or use attribute-based filtering directly in your controller constructors (even cleaner):

public class ShippingController : Controller
{
    private readonly ISender _shippingStrategy;

    public ShippingController([KeyFilter("shipping-strategy")] ISender shippingStrategy)
    {
        _shippingStrategy = shippingStrategy;
    }
}

public class CustomersController : Controller
{
    private readonly ISender _notificationStrategy;

    public CustomersController([KeyFilter("notification-strategy")] ISender notificationStrategy)
    {
        _notificationStrategy = notificationStrategy;
    }
}

With the attribute approach, you don’t need WithParameter calls on controller registrations—Autofac automatically resolves the correct keyed service based on the [KeyFilter] attribute.

Final Notes

Ensure your ConfigureServices method returns an IServiceProvider to integrate Autofac with ASP.NET Core’s DI system:

var container = builder.Build();
return new AutofacServiceProvider(container);

After these changes, ShippingController will get PostalServiceSender, CustomersController gets EmailNotifier, and all other ISender dependencies will fall back to DefaultSender as expected.

内容的提问来源于stack exchange,提问作者anton.a.popov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 09:41:20