用于依赖注入的 MVC Web API 和 Unity
Posted
技术标签:
【中文标题】用于依赖注入的 MVC Web API 和 Unity【英文标题】:MVC Web API and Unity for dependency injection 【发布时间】:2015-11-09 17:03:12 【问题描述】:我正在构建一组非常简单的控制器,我想将依赖项注入其中。
我的 Web Api 项目使用 .net 4.5.1 (vs2015),我使用 Unity 进行依赖注入(对 Unity 来说真的很新)。
这是我所做的:
-
新建项目 > ASP.Net Web 应用程序 > Web Api 项目(无身份验证)
工具 > Nuget 包管理器 > 管理解决方案的包...
搜索“Unity.MVC”并安装包。
我创建了以下接口和类:
public interface IExample
void DoWork();
public class ServiceA : IExample
public void DoWork()
Console.Write("A");
public class ServiceB : IExample
public void DoWork()
Console.Write("B");
在我的简单控制器中,我实现了这个:
public class HomeController : Controller
IExample instance;
public HomeController(IExample injected)
instance = injected;
public ActionResult Index()
ViewBag.Title = "Home Page";
return View();
我有这两个 Unity 新添加的文件:
我将以下代码添加到 UnityConfig.cs:
public static void RegisterTypes(IUnityContainer container)
// NOTE: To load from web.config uncomment the line below. Make sure to add a Microsoft.Practices.Unity.Configuration to the using statements.
// container.LoadConfiguration();
// TODO: Register your types here
//container.RegisterType<IProductRepository, ProductRepository>();
container.RegisterType<IExample, ServiceA>();
到目前为止 - 一切顺利!我按预期将 DI 放入视图中。现在我想为我的 web api 控制器做同样的事情,就像这样:
运行 - 并得到这个错误:
尝试创建“ItemController”类型的控制器时出错。确保控制器有一个无参数的公共构造函数。
我做错了什么?完全例外:
"Message": "An error has occurred.",
"ExceptionMessage": "An error occurred when trying to create a controller of type 'ItemController'. Make sure that the controller has a parameterless public constructor.",
"ExceptionType": "System.InvalidOperationException",
"StackTrace": " at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType)\r\n at System.Web.Http.Controllers.HttpControllerDescriptor.CreateController(HttpRequestMessage request)\r\n at System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__1.MoveNext()",
"InnerException":
"Message": "An error has occurred.",
"ExceptionMessage": "Type 'WebApplication2.Controllers.ItemController' does not have a default constructor",
"ExceptionType": "System.ArgumentException",
"StackTrace": " at System.Linq.Expressions.Expression.New(Type type)\r\n at System.Web.Http.Internal.TypeActivator.Create[TBase](Type instanceType)\r\n at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.GetInstanceOrActivator(HttpRequestMessage request, Type controllerType, Func`1& activator)\r\n at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType)"
提前致谢!
【问题讨论】:
由于某种原因,您的编辑被匿名用户标记为已提交,除非得到另一位用户的批准,否则不会显示。 根据您的(仍然建议的)更新,您只安装了Unity.Mvc
,它负责与 MVC 的 DependecyResolver
集成。对于 WebApi,您必须安装 Unity.WebAPI
包:nuget.org/packages/Unity.WebAPI
显示您的 WebApiConfig.cs
和 UnityMvcActivator.cs
以及最新软件包安装添加的任何新文件。
这确实有效 - 当我下载新包时,我必须重新注册类型代码!伟大的!!!!谢谢! :-)))))
【参考方案1】:
ControllerActivator
无法实例化您的HomeController
,因为它的构造函数没有标记为public
(因此它实际上是private
)。
当您根本不提供任何构造函数时,编译器会自动为您创建一个public
,但由于您正在提供一个(不是public
),因此您将结束没有公共构造函数。
试试这个:
public HomeController(IExample injected)
instance = injected;
更新:
根据您的编辑,要将 Unity 与 API 控制器集成,您还必须安装 Unity.WebAPI 包。
有关 WebAPI 集成的更多信息:http://www.asp.net/web-api/overview/advanced/dependency-injection
【讨论】:
我引用了错误的 Unity 包 - 现在将 Unity.WebAPI 包用于 MVC Web API 项目。谢谢!!【参考方案2】:要在 Web API 中使用统一的依赖注入,请使用以下步骤。
在您的 Web API 项目中安装 Unity 包。 转到包管理器控制台粘贴下面的命令以安装 Unity
Install-Package Unity.WebAPI -Version 5.3.0
安装Unity后,在Web API的APP_Start文件夹中,添加一个名为UnitConfig.cs的文件,在该文件中注册你的服务接口和服务逻辑类。
public static class UnityConfig
public static void RegisterComponents()
var container = BuildUnityContainer();
GlobalConfiguration.Configuration.DependencyResolver = new UnityDependencyResolver(container);
private static IUnityContainer BuildUnityContainer()
var container = new UnityContainer();
container.RegisterType<ICategoryService, CategoryService> ().RegisterType<UnitOfWork>(new HierarchicalLifetimeManager());
return container;
在Web API Global.asax文件的Application_Start()方法中注册上述RegisterComponents()方法
protected void Application_Start()
AreaRegistration.RegisterAllAreas();
GlobalConfiguration.Configure(WebApiConfig.Register);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
UnityConfig.RegisterComponents();
最后一步是将服务接口注入到 Web AIP 控制器构造函数中。
public CategoryController(ICategoryService Iinject)
this._categoryServices= Iinject;
【讨论】:
.RegisterType以上是关于用于依赖注入的 MVC Web API 和 Unity的主要内容,如果未能解决你的问题,请参考以下文章
ASP.NET Core Web 应用程序系列- 在ASP.NET Core中使用Autofac替换自带DI进行批量依赖注入(MVC当中应用)
ASP.NET Core Web 应用程序系列- 在ASP.NET Core中使用Autofac替换自带DI进行构造函数和属性的批量依赖注入(MVC当中应用)
ASP.NET Core Web 应用程序系列- 在ASP.NET Core中使用Autofac替换自带DI进行构造函数和属性的批量依赖注入(MVC当中应用)
ASP.NET Core Web 应用程序系列- 使用ASP.NET Core内置的IoC容器DI进行批量依赖注入(MVC当中应用)