2017-08-28 1 views
0

Je rencontre des problèmes lors de l'utilisation de l'attribut KeyFilter dans une application ASP.NET Core 2.0 WebAPI simple.Utilisation de KeyFilter avec ASP.NET Core 2.0

<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 }; 
    } 
} 

Calling "/ api/valeurs" rendement [ "value1", "valeur2", "X3"]. Mais j'attends ["value1", "value2", "X2"].

si je supprimer le troisième enregistrement (avec X3), puis

InvalidOperationException: Impossible de résoudre le service de type 'WebApplicationAutofac.IInterfaceX' tout en essayant d'activer 'WebApplicationAutofac.Controllers.ValuesController'.

Essayer de travaux résoudre directement correct:

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

Quel est le problème?

+0

Pourquoi avez-vous commenter le retour en ligne 'nouveau AutofacServiceProvider'? –

+0

'return ApplicationContainer.Resolve ()' a le même effet que 'nouveau AutofacServiceProvider (this.ApplicationContainer)' Je pense que le premier cas est mieux en raison de la résolution par conteneur. –

+0

Il semble que l'application n'utilise pas 'Autofac' et utilise le résolveur DI intégré, mais ne peut pas voir pourquoi encore –

Répondre

0

Oui, cela fonctionne très bien pour les contrôleurs WebAPI.

La solution est d'ajouter .AddControllersAsServices():

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