2017-08-28 15 views
0

シンプルな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 /値" 収率[ "値1"、 "値2"、 "X3"]。 しかし、私は["value1"、 "value2"、 "X2"]を期待しています。

私はその後

InvalidOperationExceptionが(X3との)第三登録を削除する場合:「WebApplicationAutofac.Controllers.ValuesController」をアクティブにしようとしたときに型「WebApplicationAutofac.IInterfaceX」のサービスを解決することができませんが。

正しい解決作品を指示しようとすると:

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

が間違って何ですか?

+0

なぜあなたはリターン '新しいAutofacServiceProvider'の行をコメントしましたか? –

+0

'return ApplicationContainer.Resolve ()' は と同じ効果があります。 '新しいAutofacServiceProvider(this.ApplicationContainer)' コンテナによる解決のために最初のケースが優れていると思います。 –

+0

アプリケーションが 'Autofac'を使用せず、内蔵のDIリゾルバを使用していますが、理由を見ることができないようです。 –

答えて

0

はい、これはWebAPIコントローラでは非常にうまく動作します。

ソリューションは.AddControllersAsServicesを追加することです():

public IServiceProvider ConfigureServices(IServiceCollection services) 
{ 
    services.AddMvc().AddControllersAsServices(); 
関連する問題