シンプルな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");
が間違って何ですか?
なぜあなたはリターン '新しいAutofacServiceProvider'の行をコメントしましたか? –
'return ApplicationContainer.Resolve()' は と同じ効果があります。 '新しいAutofacServiceProvider(this.ApplicationContainer)' コンテナによる解決のために最初のケースが優れていると思います。 –
アプリケーションが 'Autofac'を使用せず、内蔵のDIリゾルバを使用していますが、理由を見ることができないようです。 –