c# - 确保 Controller 有一个无参数的公共(public)构造函数错误

标签 c# asp.net-mvc asp.net-web-api unity-container

我已经关注了这个 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 功能来创建 DbContextDbContext 是一种特殊类型,不应自动连接。它是一种框架类型,你应该 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/

相关文章:

c# - 创建 ICryptoTransform 时出现 System.Security.CryptpgraphicUnexpectedOperationException

c# - 如何将带有键/值的数组转换为 JSON c#

c# - 节点的内部文本忽略子节点的内部文本

javascript - 将 kendo grid DataSourceRequest 从 javascript 传递到 ASP.NET

asp.net-mvc - 保护 ASP.Net MVC 站点

c# - 单个 using 语句,多个 MVC View

c# - 获取 SortedDictionary 中的最后一个元素

c# - 带有 DateTimeOffset 的 OData 函数?范围

c# - Web API 和 MVC 异常处理

c# - 当找到路由/url但没有找到它背后的资源时返回什么?