在ASP.NET Core 2.0中使用KeyFilter

在ASP.NET Core 2.0中使用KeyFilter

问题描述:

我在使用简单的ASP.NET Core 2.0 WebAPI应用程序中的KeyFilter属性时遇到了问题。在ASP.NET Core 2.0中使用KeyFilter

<PackageReference Include="Autofac" Version="4.6.1" /> 
<PackageReference Include="Autofac.Extensions.DependencyInjection" Version="4.2.0" /> 
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.0" /> 

的Program.cs:

public class Program 
{ 
    public static void Main(string[] args) 
    { 
     BuildWebHost(args).Run(); 
    } 

    public static IWebHost BuildWebHost(string[] args) => 
     WebHost.CreateDefaultBuilder(args) 
       .ConfigureServices(services => services.AddAutofac()) 
       .UseStartup<Startup>() 
       .Build(); 
    } 

Startup.cs:

public Startup(IConfiguration configuration) 
{ 
    Configuration = configuration; 
} 

public IConfiguration Configuration { get; } 

public IContainer ApplicationContainer { get; private set; } 

// This method gets called by the runtime. 
// Use this method to add services to the container. 
public IServiceProvider ConfigureServices(IServiceCollection services) 
{ 
    services.AddMvc(); 

    // Autofac 
    var builder = new ContainerBuilder(); 

    builder.Populate(services); 
    builder.RegisterType<ClassX1>() 
      .Keyed<IInterfaceX>("first") 
      .WithParameter("name", "X1") 
      .SingleInstance(); 

    builder.RegisterType<ClassX1>() 
      .Keyed<IInterfaceX>("second") 
      .WithParameter("name", "X2") 
      .SingleInstance(); 

    builder.RegisterType<ClassX1>() 
      .As<IInterfaceX>() 
      .WithParameter("name", "X3") 
      .SingleInstance(); 

    builder.RegisterType<ValuesController>() 
      .WithAttributeFiltering(); 

    ApplicationContainer = builder.Build(); 

    return ApplicationContainer.Resolve<IServiceProvider>(); 
    // return new AutofacServiceProvider(this.ApplicationContainer); 
} 

// This method gets called by the runtime. 
// Use this method to configure the HTTP request pipeline. 
public void Configure(IApplicationBuilder app, IHostingEnvironment env) 
{ 
    if (env.IsDevelopment()) 
    { 
     app.UseDeveloperExceptionPage(); 
    } 

    app.UseMvc(); 
} 

ClassX1.cs:

public class ClassX1: IInterfaceX 
{ 
    public ClassX1(string name) 
    { 
     Name = name; 
    } 

    public string Name { get; } 
} 

IInterfaceX.cs:

public interface IInterfaceX 
{ 
    string Name { get; } 
} 

ValuesController.cs:

[Route("api/[controller]")] 
public class ValuesController : Controller 
{ 
    private readonly IInterfaceX _x; 

    public ValuesController([KeyFilter("second")] IInterfaceX x) 
    { 
     _x = x; 
    } 

    // GET api/values 
    [HttpGet] 
    public IEnumerable<string> Get() 
    { 
     return new string[] { "value1", "value2", _x.Name }; 
    } 
} 

呼叫 “/ API /值” 产量[ “VALUE1”, “VALUE2”, “X 3”]。 但我期待[“value1”,“value2”,“X2”]。

如果删除了第三注册(与X3)然后

InvalidOperationException异常:无法为类型“WebApplicationAutofac.IInterfaceX”解决服务而试图激活“WebApplicationAutofac.Controllers.ValuesController”。

试图直接解决工作正确:

var temp = ApplicationContainer.ResolveKeyed<IInterfaceX>("second"); 

有什么不对?

+0

你为什么要发表评论返回'新AutofacServiceProvider'线? –

+0

'return ApplicationContainer.Resolve ()' 与 'new AutofacServiceProvider(this.ApplicationContainer)' 具有相同的效果我认为第一种情况因容器的分辨率而更好。 –

+0

它看起来应用程序不使用'Autofac'并使用内置的DI解析器,但看不到为什么 –

是的,它对WebAPI控制器非常酷。

的解决方案是增加.AddControllersAsServices():

public IServiceProvider ConfigureServices(IServiceCollection services) 
{ 
    services.AddMvc().AddControllersAsServices();