Assurez-vous que le contrôleur a une erreur de constructeur public sans paramètre

J’ai suivi ce tutoriel qui a bien fonctionné, jusqu’à ce que je modifie mon DbContext pour avoir un constructeur supplémentaire. J’ai maintenant des problèmes avec la résolution et je ne sais pas quoi faire pour résoudre ce problème. Existe-t-il un moyen simple de le forcer à saisir le constructeur sans paramètre ou je ne l’aborde pas correctement?

DbContext avec deux constructeurs:

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

Constructeur SiteController :

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

Dépôt:

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

Code UnityResolver :

 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 GetServices(Type serviceType) { try { return _container.ResolveAll(serviceType); } catch (ResolutionFailedException) { return new List(); } } public IDependencyScope BeginScope() { var child = _container.CreateChildContainer(); return new UnityResolver(child); } public void Dispose() { _container.Dispose(); } } 

WebApiConfig:

 var container = new UnityContainer(); container.RegisterType(new HierarchicalLifetimeManager()); config.DependencyResolver = new UnityResolver(container); 

Erreur de l’appel WebApi:

System.InvalidOperationException: une erreur s’est produite lors de la tentative de création d’un contrôleur de type ‘SiteController’. Assurez-vous que le contrôleur dispose d’un constructeur public sans paramètre.

 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.d__0.MoveNext() 

InnerException: System.ArgumentException: Type ‘Dashboard.Web.Controllers.SiteController’ n’a pas de constructeur par défaut.

 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) 

Le tutoriel était génial et a bien fonctionné jusqu’à ce que j’ajoute le deuxième constructeur.

Ce qui se passe, c’est que vous êtes mordu par ce problème . En gros, ce qui s’est passé, c’est que vous n’avez pas enregistré explicitement vos contrôleurs dans votre conteneur. Unity tente de résoudre les types de béton non enregistrés pour vous, mais comme il ne peut pas le résoudre (en raison d’une erreur dans votre configuration), il renvoie null. Il est obligé de renvoyer null, car l’API Web le force à le faire en raison du contrat IDependencyResolver . Comme Unity renvoie null, Web API essaiera de créer le contrôleur lui-même, mais comme il n’a pas de constructeur par défaut, il lancera l’exception “Assurez-vous que le contrôleur a un constructeur public sans paramètre”. Ce message d’exception est trompeur et n’explique pas la cause réelle.

Vous auriez vu un message d’exception beaucoup plus clair si vous enregissortingez explicitement vos contrôleurs, et c’est pourquoi vous devez toujours enregistrer tous les types de racine explicitement.

Mais bien sûr, l’erreur de configuration provient de l’ajout du second constructeur à votre DbContext . Unity essaie toujours de choisir le constructeur avec le plus d’arguments, mais il n’a aucune idée de la manière de résoudre ce constructeur particulier.

La véritable cause est que vous essayez d’utiliser les fonctionnalités de câblage automatique d’Unity pour créer DbContext . DbContext est un type spécial qui ne devrait pas être câblé automatiquement. Il s’agit d’un type de framework et vous devez donc vous contenter de l’enregistrer en utilisant un délégué usine :

 container.Register( new InjectionFactory(c => new DashboardDbContext()));