C# Unity.WebApi |确保控制器具有无参数公共构造函数
我正在ASP.NET WebApi解决方案中使用Unity.WebApi NuGet包(Unity 4.0.1和Unity.WebApi 5.2.3)。我面临的问题是,当尝试运行代码时,我会得到错误:C# Unity.WebApi |确保控制器具有无参数公共构造函数,c#,asp.net-web-api,dependency-injection,inversion-of-control,unity-container,C#,Asp.net Web Api,Dependency Injection,Inversion Of Control,Unity Container,我正在ASP.NET WebApi解决方案中使用Unity.WebApi NuGet包(Unity 4.0.1和Unity.WebApi 5.2.3)。我面临的问题是,当尝试运行代码时,我会得到错误:确保控制器具有无参数公共构造函数。我在这里搜索过类似的线程,但找不到任何与我的问题相匹配的线程 请不要只说“添加一个无参数构造函数”,因为这表明你显然不知道什么是IoC,为什么这句话毫无意义,违背了IoC的宗旨。我之所以这么说,是因为我在很多其他线程上都看到了这一点 这是我的Startup.cs(我
确保控制器具有无参数公共构造函数
。我在这里搜索过类似的线程,但找不到任何与我的问题相匹配的线程
请不要只说“添加一个无参数构造函数”,因为这表明你显然不知道什么是IoC,为什么这句话毫无意义,违背了IoC的宗旨。我之所以这么说,是因为我在很多其他线程上都看到了这一点
这是我的Startup.cs(我使用的是Owin,所以我没有全局.asax):
这是我的UnityConfig.cs:
public static class UnityConfig {
public static void RegisterComponents() {
var container = new UnityContainer();
// Register controller
container.RegisterType<MyController>();
// Register interface
container.RegisterType<IService, Service>();
GlobalConfiguration.Configuration.DependencyResolver = new UnityDependencyResolver(container);
}
}
编辑
我删除了using语句,因为无论using语句是否存在,人们都很难理解问题的发生。根据我的经验,出现这种情况时有两种不同的情况 一,。 确保可以解析
服务
构造函数中的所有参数。它是否有您尚未注册的依赖项
二,。
确保使用Web API注册Unity。像这样:
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Routes and other stuff here...
var container = IocContainer.Instance; // Or any other way to fetch your container.
config.DependencyResolver = new UnityDependencyResolver(container);
}
}
示例如下:
编辑1:
正如注释中提到的@NightOwl888,您不应该处置容器。注册是在容器上注册的,当容器被释放时,它将不知道如何解决依赖关系。这可能会导致您看到的错误
编辑2:
由于您正在使用Owin,您应该能够执行以下操作:
public void Configuration(IAppBuilder appBuilder)
{
// Configure Web API for self-host.
HttpConfiguration config = new HttpConfiguration();
config.DependencyResolver = new UnityDependencyResolver(
UnityConfig.GetConfiguredContainer());
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
appBuilder.UseWebApi(config);
}
并将您的UnityConfiguration更新为:
public static class UnityConfig {
public static IUnityContainer GetConfiguredContainer() {
var container = new UnityContainer();
// Register controller
container.RegisterType<MyController>();
// Register interface
container.RegisterType<IService, Service>();
//This is done in Startup instead.
//GlobalConfiguration.Configuration.DependencyResolver = new UnityDependencyResolver(container);
return container;
}
}
公共静态类UnityConfig{
公共静态IUnityContainer GetConfiguredContainer(){
var container=new UnityContainer();
//寄存器控制器
container.RegisterType();
//寄存器接口
container.RegisterType();
//这是在启动时完成的。
//GlobalConfiguration.Configuration.DependencyResolver=新的UnityDependencyResolver(容器);
返回容器;
}
}
从这个来源:
在此方法中,HttpConfiguration.DependencyResolver设置为
UnityDependencyResolver实例。这是必要的,以便承包商
可以在webApi控制器中使用注入。这个
UnityDependencyResolver类与
Unity.WebApi.UnityDependencyResolver类。未使用Unity.WebApi
因为这是一个自托管的OWIN应用程序
将
dependencysolver
设置为启动时创建的HttpConfiguration
,而不是GlobalConfiguration.Configuration
,并确保所有服务构造函数都是公共的,希望这有助于确保也被注入的任何嵌套类型都被正确解析。即使嵌套类型解析不正确,您也会在控制器级别收到错误消息。此问题的另一个可能调查路径和原因。我在全局异常处理程序上设置断点,并查看异常实例上的嵌套异常属性。我得到的错误是没有一个可访问的构造函数,这是真的,因为我想要注入的类型确实有一个私有构造函数(我正在重构一个单例)
因此,我刚刚将另一个指定为受保护,以快速解决问题
public Repository() : this( ... ) { ... }
// if need to make public, make sure that the dependency injection container
// will choose the parameterless constructor;
// Unity has had issues with that by default
protected Repository(DbContext context) : base() { ... }
在我看来,Unity本可以找到“可调用”构造函数——因为它没有注册DbContext(或任何派生上下文)
请注意,默认情况下,Unity
选择具有最大参数数的构造函数
因此,是的,也可以像前面所描述的那样用InjectionConstructorAttribute
来修饰适当的构造函数,但是我的数据访问层中甚至没有Unity
引用(我不想)
请告诉我这种行为在以后的版本中是否发生了变化。不幸的是,这些答案对我都不起作用。我已经通过以下步骤使用了smoksnes提供的方法:
我的问题是通过使用特定于web api的unity软件包(unity.AspNet.WebApi)而不是Microsoft指南中描述的通用.net软件包解决的 你能分享服务类的详细信息吗?您是否缺少注册服务类所需的任何类?可能是您的容器在MVC实际使用之前就已经被释放了吗?它抛出这个错误是不符合逻辑的,但是可能。请尝试将
var container=new UnityContainer()
从using块中取出。否则没有要共享的详细信息。假设它所做的只是有一个打印“Hello World”的方法。夜猫子我最初是这么做的,所以事实并非如此。后来,在试图解决这个问题的过程中,出现了使用问题。我认为这是一个不可靠的事情,因为它是基于Owin的,但我不确定。@NightOwl888是正确的。将unity容器和http配置从使用语句中去掉。它们都在收到第一个web请求之前被处理。@TylerOhlsen无论是否存在USING,都会产生相同的错误结果。请参阅我回答夜猫子问题的评论。using语句是在这些问题发生之后出现的,它是在尝试解决问题的过程中添加的。不管是否有使用,我仍然看到同样的问题。另外,假设服务中没有任何内容,并且它的默认构造函数为空。或者如果你的imagi
public static class UnityConfig {
public static IUnityContainer GetConfiguredContainer() {
var container = new UnityContainer();
// Register controller
container.RegisterType<MyController>();
// Register interface
container.RegisterType<IService, Service>();
//This is done in Startup instead.
//GlobalConfiguration.Configuration.DependencyResolver = new UnityDependencyResolver(container);
return container;
}
}
public Repository() : this( ... ) { ... }
// if need to make public, make sure that the dependency injection container
// will choose the parameterless constructor;
// Unity has had issues with that by default
protected Repository(DbContext context) : base() { ... }