Question

J'essaie de configurer la carte de structure VER 3.0.5.0 avec Web API 2.

J'ai suivi cette implémentation: Configuration de l'injection de dépendanceAvec ASP.NET Web API 2.1

Cependant, je reçois cette erreur lorsque vous faites un get contre mon complexeSontroller:

une erreur s'est produite lors de la tentative de création d'un contrôleur de type "complexesController".Assurez-vous que le contrôleur dispose d'un constructeur public sans paramètre.

Quelqu'un peut-il voir ce qui ne va pas avec ma configuration StructureMap?La méthode de création n'est jamais appelée.

Ceci est ma mise en œuvre:

public class StructureMapControllerActivator : IHttpControllerActivator
{
    private readonly IContainer _container;

    public StructureMapControllerActivator(IContainer container)
    {
        if (container == null) throw new ArgumentNullException("container");
        _container = container;
    }

    public IHttpController Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType)
    {
        try
        {                
            var scopedContainer = _container.GetNestedContainer();
            scopedContainer.Inject(typeof(HttpRequestMessage), request);
            request.RegisterForDispose(scopedContainer);
            return (IHttpController)scopedContainer.GetInstance(controllerType);
        }
        catch (Exception e)
        {
            // TODO : Logging
            throw e;
        }
    }
}

Cette méthode est dans mon démarrage ...

public void InitializeContainer()
    {
        // STRUCTURE MAP
        Container container = new Container();
        GlobalConfiguration.Configuration.Services.Replace(typeof(IHttpControllerActivator), new StructureMapControllerActivator(container));

        container.Configure(x => x.For<IForumRepository>().Use<ForumRepository>());
        container.Configure(x => x.For<IComplexRepository>().Use<ComplexRepository>());        
    }

.. Et ceci est le contrôleur:

 public class ComplexesController : ApiController
{

    private IComplexRepository _repo;

    public ComplexesController(IComplexRepository repo)
    {
        _repo = repo;
    }

    // GET: api/Complexes
    public IList<Complex> GetComplexes()
    {
        var complexes = _repo.GetList();
        return complexes;
    }
    ...

Ma classe de démarrage complète

[assembly: OwinStartup(typeof(AngularJSAuthentication.API.Startup))]
namespace AngularJSAuthentication.API
{
  public class Startup
   {
    public void Configuration(IAppBuilder app)
    {
        HttpConfiguration config = new HttpConfiguration();
        WebApiConfig.Register(config);
        app.UseWebApi(config);
    }

  }
}

Était-ce utile?

La solution

Le problème ici est que vous enregistrez votre activateur de service avec un objet GlobalConfiguration et non votre objet httpconfiguration.Dans ce scénario, l'objet GlobalConfiguration n'est jamais utilisé car il est remplacé par l'objet httpconfiguration.Afin de résoudre votre problème, vous devez remplacer votre méthode InitializContainer () avec ce qui suit.

public void InitializeContainer(HttpConfiguration config)
    {
        // STRUCTURE MAP
        Container container = new Container();
        config.Services.Replace(typeof(IHttpControllerActivator), new StructureMapControllerActivator(container));

        container.Configure(x => x.For<IForumRepository>().Use<ForumRepository>());
        container.Configure(x => x.For<IComplexRepository>().Use<ComplexRepository>());        
    }

Vous devez ensuite transmettre l'objet httpconfiguration de votre classe de démarrage à la nouvelle méthode InitializContainer ().

J'espère que cela aide.

-b

Autres conseils

J'essaie de mieux comprendre le cycle de vie complet.Je pense que ma configuration peut être légèrement différente de ce qui précède.Voici ce qui a fonctionné pour moi.

public partial class Startup
{
    public void Configuration(IAppBuilder app)
    {                       
        var config = new HttpConfiguration();
        var container = IocConfig.Setup();

        // Allow a controller to be declared without a parameterless constructor
        config.DependencyResolver = new DependencyResolver(container);

        config.Services.Add( typeof(IExceptionLogger), new GlobalExceptionLogger( container.GetInstance<ILoggingService>()));

        // Web API routes
        config.MapHttpAttributeRoutes();

        // Setup Authentication
        ConfigureOAuth(app, container);

        var corsOptions = CorsOptions.AllowAll;

        app.UseCors(corsOptions);

        // Add ASP.Net Web API to OWIN pipeline
        app.UseWebApi(config);
    }
}

Cela a fonctionné après que j'ai ajouté cette ligne:

// Allow a controller to be declared without a parameterless constructor
config.DependencyResolver = new DependencyResolver(container);

Vous devez obtenir que mes chargements de conteneur Var à partir d'une classe statique appelée iocconfig avec une méthode de configuration statique.C'est là que les interfaces sont mappées sur leurs implémentations concrètes.

En outre, vous pouvez probablement ignorer la ligne GlobalExceptionLogger si vous souhaitez utiliser mon exemple complet.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top