1

I have a Web Api with controllers that have constructors with parameters, like this:

public class UserController : ApiController
    {
        private UserService userService;
        public UserController(UserService userService)
        {
            this.userService = userService;
        }
}

I'm using Dependency Injection. I followed this tutorial and this is how it looks now:

public static class UnityConfig
    {
        public static void RegisterComponents()
        {
            var container = new UnityContainer();

            // register all your components with the container here
            // it is NOT necessary to register your controllers

            // e.g. container.RegisterType<ITestService, TestService>();

            GlobalConfiguration.Configuration.DependencyResolver = new UnityDependencyResolver(container);
        }
    }
public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            // Web API configuration and services
            var container = new UnityContainer();
            container.RegisterType<UserService>().RegisterType<IUnitOfWork, UnitOfWork>(new HierarchicalLifetimeManager());
            container.RegisterType<ProviderService>().RegisterType<UserService>().RegisterType<IUnitOfWork, UnitOfWork>(new HierarchicalLifetimeManager());
            container.RegisterType<TransactionService>().RegisterType<UserService>().RegisterType<IUnitOfWork, UnitOfWork>(new HierarchicalLifetimeManager());
            config.DependencyResolver = new UnityResolver(container);
...
}

When I run it from Visual Studio and test it through Postman it works just fine. But when I publish the Api and try to run it from the published version I get this error:

ExceptionMessage: An error occurred when trying to create a controller of type 'UserController'. Make sure that the controller has a parameterless public constructor.

en System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType)
en System.Web.Http.Controllers.HttpControllerDescriptor.CreateController(HttpRequestMessage request)
en System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__1.MoveNext()

System.ArgumentException: The type 'PaymentManagement.Web.Api.Controllers.UserController' doesn't have a predeterminate constructor

en System.Linq.Expressions.Expression.New(Type type)
en System.Web.Http.Internal.TypeActivator.Create[TBase](Type instanceType)
en System.Web.Http.Dispatcher.DefaultHttpControllerActivator.GetInstanceOrActivator(HttpRequestMessage request, Type controllerType, Func`1& activator)
en System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType)

This is how I do to publish it: enter image description here

I used to get this same error when running it from Visual Studio before adding the unity container. But I don't know what I'm missing now.

Steven
  • 166,672
  • 24
  • 332
  • 435
moondaisy
  • 4,303
  • 6
  • 41
  • 70
  • Regarding DI: The UserController depends on UserService. It should not depend on details. Create a interface IUserService of UserService which UserController depends on. Then you break the UserControllers dependency on UserService. – Marcus Höglund Oct 18 '16 at 18:20
  • You should register your controllers explicitly. When you do, you will see a more expressive exception that will tell you what is wrong with your configuration. – Steven Oct 18 '16 at 20:23

1 Answers1

0

In the end the problem was that EntityFramework.SqlServer.dll was not getting added to the publish folder. I found the solution here and here

By coping that dll to the bin folder of my published API the problem was fixed.

Community
  • 1
  • 1
moondaisy
  • 4,303
  • 6
  • 41
  • 70