Constructor configuration error without constructor parameters

I am trying to customize the structure of map ver 3.0.5.0 using Web API 2.

I implemented this implementation: Configuring dependency injection using ASP.NET Web API 2.1

However, I get this error when I try to access my ComplexesController:

An error occurred while trying to create a controller of type "ComplexesController". Make sure that the controller does not have a constructor without parameters.

Can anyone see what is wrong with my mapmap configuration? The Create method is never called.

This is my implementation:

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

This method is in my startup ...

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

.. and this is the controller:

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

My full launch class

 [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); } } } 
+6
source share
2 answers

The problem is that you are registering a service activator with a GlobalConfiguration object, and not with an HttpConfiguration object. In this case, the GlobalConfiguration object is never used, because it is replaced by the HttpConfiguration object. To solve the problem, you should replace your InitializeContainer () method with the following.

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

you must pass the HttpConfiguration object from your Startup class to the new InitializeContainer () method.

Hope this helps.

-B

+9
source

I am trying to get a full understanding of the full life cycle. I think my setup may be slightly different from the above. Here is what worked for me.

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

It worked after adding this line:

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

You should get my container container loaded from the static IocConfig class with a static installation method. Here the interfaces are mapped to their specific implementations.

Alternatively, you can probably ignore the GlobalExceptionLogger line if you want to use my full example.

0
source

Source: https://habr.com/ru/post/973061/


All Articles