我已经关注了这个 tutorial效果很好,直到我修改了我的 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();
}
}
WebApi配置:
var container = new UnityContainer();
container.RegisterType<IDashboardRepository, DashboardRepository>(new HierarchicalLifetimeManager());
config.DependencyResolver = new UnityResolver(container);
WebApi 调用错误:
System.InvalidOperationException: An error occurred when trying to create a controller of type 'SiteController'. Make sure that the controller has a parameterless public constructor.
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: 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)
教程很棒,在我添加第二个构造函数之前一直对我有用。
最佳答案
发生的事情是你被 this problem 咬了.基本上,发生的事情是您没有在您的容器中明确注册您的 Controller 。 Unity 尝试为您解析未注册的具体类型,但由于它无法解析它(由您的配置错误引起),它返回 null。它被迫返回 null,因为 Web API 根据 IDependencyResolver
协定强制它这样做。由于 Unity 返回 null,Web API 将尝试自己创建 Controller ,但由于它没有默认构造函数,因此会抛出“确保 Controller 具有无参数公共(public)构造函数”异常。此异常消息具有误导性,无法解释真正的原因。
如果您显式注册您的 Controller ,您会看到更清晰的异常消息,这就是为什么您应该始终显式注册所有根类型。
当然,配置错误来自于您将第二个构造函数添加到您的 DbContext
。 Unity 总是尝试选择参数最多的构造函数,但它不知道如何解析这个特定的构造函数。
所以真正的原因是您正在尝试使用 Unity 的 Autowiring 功能来创建 DbContext
。 DbContext
是一种特殊类型,不应自动连接。它是一种框架类型,你应该 therefore fallback to registering it using a factory delegate :
container.Register<DashboardDbContext>(
new InjectionFactory(c => new DashboardDbContext()));
关于c# - 确保 Controller 有一个无参数的公共(public)构造函数错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24254189/