Убедитесь, что контроллер имеет ошибку открытого конструктора без параметров
Я следил за этим учебник, который работал отлично, пока я не изменил мой DbContext
чтобы иметь дополнительный конструктор. Теперь у меня возникли проблемы с разрешением и не знаю, что делать, чтобы исправить это. Есть ли простой способ заставить его захватить конструктор без параметров или я подхожу к этому неправильно?
DbContext
С двумя конструкторами:
public class DashboardDbContext : DbContext
{
public DashboardDbContext() : base("DefaultConnection") { }
public DashboardDbContext(DbConnection dbConnection, bool owns)
: base(dbConnection, owns) { }
}
SiteController
конструктор:
private readonly IDashboardRepository _repo;
public SiteController(IDashboardRepository repo)
{
_repo = repo;
}
репозитория:
DashboardDbContext _context;
public DashboardRepository(DashboardDbContext context)
{
_context = context;
}
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<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);
ошибка от вызова WebApi:
5 ответов:
происходит то, что тебя укусил проблема. В основном, произошло то, что вы не зарегистрировали свои контроллеры явно в своем контейнере. Unity пытается разрешить незарегистрированные конкретные типы для вас, но поскольку он не может разрешить его (вызванный ошибкой в вашей конфигурации), он возвращает null. Он вынужден возвращать null, потому что веб-API заставляет его делать это из-за
IDependencyResolver
контракт. Поскольку Unity возвращает null, Web API попытается создать контроллер сам, но поскольку у него нет конструктора по умолчанию, он бросит исключение "убедитесь, что контроллер имеет открытый конструктор без параметров". Это сообщение об ошибке вводит в заблуждение и не объясняет истинную причину.вы бы увидели гораздо более четкое сообщение об исключении, если бы вы зарегистрировали свои контроллеры явно, и именно поэтому вы всегда должны регистрировать все корневые типы явно.
но, конечно, ошибка конфигурации исходит от вас добавление второй конструктор для вашего
DbContext
. Unity всегда пытается выбрать конструктор с наибольшим количеством аргументов, но он понятия не имеет, как решить этот конкретный конструктор.таким образом, реальная причина заключается в том, что вы пытаетесь использовать возможности автоматической проводки Unity для создания
DbContext
.DbContext
это специальный тип, который не должен быть автоматически подключен. Это тип фреймворка, и вы должны поэтому возврат к регистрации его с помощью делегата фабрики:container.Register<DashboardDbContext>( new InjectionFactory(c => new DashboardDbContext()));
в моем случае это было из - за исключения внутри конструктора моей введенной зависимости (в вашем примере-внутри конструктора DashboardRepository). Исключение было поймано где-то внутри инфраструктуры MVC. Я нашел это после того, как я добавил журналы в соответствующих местах.
У меня была та же проблема, и я решил ее, внеся изменения в UnityConfig.cs-файл для решения проблемы зависимости в UnityConfig.cs файл, который вы должны добавить:
public static void RegisterComponents() { var container = new UnityContainer(); container.RegisterType<ITestService, TestService>(); DependencyResolver.SetResolver(new UnityDependencyResolver(container)); }
иногда потому, что вы решаете свой интерфейс в ContainerBootstraper.cs очень трудно поймать ошибку. В моем случае произошла ошибка в разрешении реализации интерфейса, который я ввел в контроллер api. Я не мог найти ошибку, потому что у меня есть разрешить интерфейс в моем bootstraperContainer, как это:
container.RegisterType<IInterfaceApi, MyInterfaceImplementaionHelper>(new ContainerControlledLifetimeManager());
затем я добавляю следующую строку в мой загрузочный контейнер:container.RegisterType<MyController>();
поэтому, когда я компилирую проект, компилятор жаловался и остановился в строке выше и показал ошибку.
у меня была та же проблема. Я гуглил его в течение двух дней. Наконец я случайно заметил, что проблема была модификаторы доступа конструктора контроллера. Я не ставил
public
ключевое слово за конструктором контроллера.public class MyController : ApiController { private readonly IMyClass _myClass; public MyController(IMyClass myClass) { _myClass = myClass; } }
Я добавляю этот опыт в качестве другого ответа, возможно, кто-то еще сделал аналогичную ошибку.