Make sure the controller has an error without parameters

I followed this tutorial , which did a great job until I changed my DbContext to have an additional constructor. I'm having permission issues, and I'm not sure what to do to fix this. Is there an easy way to make it capture a constructor without parameters, or am I approaching this incorrectly?

DbContext with two constructors:

 public class DashboardDbContext : DbContext { public DashboardDbContext() : base("DefaultConnection") { } public DashboardDbContext(DbConnection dbConnection, bool owns) : base(dbConnection, owns) { } } 

SiteController constructor:

 private readonly IDashboardRepository _repo; public SiteController(IDashboardRepository repo) { _repo = repo; } 

Repository:

 DashboardDbContext _context; public DashboardRepository(DashboardDbContext context) { _context = context; } 

UnityResolver code:

 public class UnityResolver : IDependencyResolver { private readonly IUnityContainer _container; public UnityResolver(IUnityContainer container) { _container = container; } public object GetService(Type serviceType) { try { return _container.Resolve(serviceType); } catch (ResolutionFailedException) { return null; } } public IEnumerable<object> GetServices(Type serviceType) { try { return _container.ResolveAll(serviceType); } catch (ResolutionFailedException) { return new List<object>(); } } public IDependencyScope BeginScope() { var child = _container.CreateChildContainer(); return new UnityResolver(child); } public void Dispose() { _container.Dispose(); } } 

WebApiConfig:

 var container = new UnityContainer(); container.RegisterType<IDashboardRepository, DashboardRepository>(new HierarchicalLifetimeManager()); config.DependencyResolver = new UnityResolver(container); 

Error when calling WebApi:

System.InvalidOperationException: An error occurred while trying to create a controller of type SiteController. Make sure that the controller does not have a constructor without parameters.

 at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType) at System.Web.Http.Controllers.HttpControllerDescriptor.CreateController(HttpRequestMessage request) at System.Web.Http.Dispatcher.HttpControllerDispatcher.SendAsyncCore(HttpRequestMessage request, CancellationToken cancellationToken) at System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__0.MoveNext() 

InnerException: System.ArgumentException: The type "Dashboard.Web.Controllers.SiteController" does not have a default constructor.

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

The tutorial was great and worked fine for me until I added a second constructor.

+91
c # asp.net-mvc asp.net-web-api unity-container
Jun 17 '14 at 0:41
source share
8 answers

What happens because you have bitten this problem . Basically, what happened is that you did not register your controllers explicitly in your container. Unity tries to allow you unregistered specific types, but since it cannot solve it (caused by an error in your configuration), it returns null. It is forced to return null because the Web API forces it to do this because of the IDependencyResolver contract. Since Unity returns null, the Web API will try to create the controller itself, but since it does not have a default constructor, it will throw a "Make sure the controller has an exception without parameters" exception. This error message is misleading and does not explain the true cause.

You would see a much clearer exception message if you explicitly registered your controllers and why you should always register all root types explicitly.

But, of course, a configuration error occurs due to the addition of a second constructor to your DbContext . Unity always tries to choose a constructor with most arguments, but does not know how to enable this particular constructor.

So, the real reason is that you are trying to use the Unity auto-wiring capabilities to create a DbContext . DbContext is a special type that should not be automatically connected. This is a type of structure, and you must refuse to register with the factory delegate :

 container.Register<DashboardDbContext>( new InjectionFactory(c => new DashboardDbContext())); 
+117
Jun 17 '14 at 6:31
source share

In my case, it was due to an exception inside the constructor of my nested dependency (in your example, inside the constructor of DashboardRepository). An exception was found somewhere inside the MVC infrastructure. I found this after adding the magazines to the appropriate places.

+42
Jan 13 '15 at 6:51
source share

I had the same problem and resolved it by making changes to the UnityConfig.cs file. To resolve the dependency problem in the UnityConfig.cs file, you must add:

 public static void RegisterComponents() { var container = new UnityContainer(); container.RegisterType<ITestService, TestService>(); DependencyResolver.SetResolver(new UnityDependencyResolver(container)); } 
+5
Jun 25 '16 at 9:39
source share

Sometimes, since you allow your interface in ContainerBootstraper.cs, it is very difficult to catch an error. In my case, an error occurred in resolving the implementation of the interface that I entered into the api controller. I could not find the error because I enable the interface in my bootstraperContainer as follows: container.RegisterType<IInterfaceApi, MyInterfaceImplementaionHelper>(new ContainerControlledLifetimeManager());
then I add the following line to my container for bootstrapping: container.RegisterType<MyController>(); therefore, when I compile the project, the compiler complained and stopped at the line above and showed an error.

+4
Jun 03 '16 at 4:59
source share

I have the same problem. I googled it for two days. Finally, I accidentally noticed that the problem was in the access modifier of the Controller constructor. I did not put the word public key behind the Controllers constructor.

 public class MyController : ApiController { private readonly IMyClass _myClass; public MyController(IMyClass myClass) { _myClass = myClass; } } 

I am adding this experience as another answer, maybe someone else made a similar mistake.

+2
May 05 '18 at 10:34
source share

If you have an interface in your controller

 public myController(IXInterface Xinstance){} 

You must register them in the Inpendency Injection container.

 container.Bind<IXInterface>().To<XClass>().InRequestScope(); 
0
Oct 17 '18 at 8:37
source share

I got this error when I accidentally defined a property as a specific type of object instead of the type of interface that I defined in UnityContainer.

For example:

UnityContainer definition:

 var container = new UnityContainer(); container.RegisterInstance(typeof(IDashboardRepository), DashboardRepository); config.DependencyResolver = new UnityResolver(container); 

SiteController (wrong path - notification repo type):

 private readonly DashboardRepository _repo; public SiteController(DashboardRepository repo) { _repo = repo; } 

SiteController (correct path):

 private readonly IDashboardRepository _repo; public SiteController(IDashboardRepository repo) { _repo = repo; } 
0
Nov 29 '18 at 8:40
source share

If you use UnityConfig.cs to maintain type matching, as shown below.

 public static void RegisterTypes(IUnityContainer container) { container.RegisterType<IProductRepository, ProductRepository>(); } 

You must report **webApiConfig.cs** about the container

 config.DependencyResolver = new Unity.AspNet.WebApi.UnityDependencyResolver(UnityConfig.Container); 
0
Jun 23 '19 at 16:12
source share



All Articles