我正在构建一组非常简单的控制器,我想将依赖项注入其中。
我的Web Api项目正在使用.net 4.5.1(vs2015),我正在使用Unity进行依赖注入(对于Unity来说真的很新)。
这就是我所做的:
我创建了以下接口和类:
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控制器做同样的事情,如下:
运行 - 并收到此错误:
尝试创建类型&#39; ItemController&#39;的控制器时发生错误。确保控制器具有无参数的公共构造函数。
我做错了什么?完全例外:
{
"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)"
}
}
提前致谢!
答案 0 :(得分:3)
ControllerActivator
无法实例化您的HomeController
,因为其构造函数未标记为public
(因此它实际上是private
)。
如果您根本没有提供任何构造函数,编译器会自动为您创建一个public
,但由于您 提供一个(不是public
)你最终没有公共构造函数。
试试这个:
public HomeController(IExample injected)
{
instance = injected;
}
<强>更新强>
根据您的编辑,要将Unity与API控制器集成,您还必须安装Unity.WebAPI包。
有关WebAPI inegration的更多信息:http://www.asp.net/web-api/overview/advanced/dependency-injection
答案 1 :(得分:0)
在Web API中使用依赖注入与统一使用以下步骤。
在Web API项目中安装Unity包。 转到Package manager console paste下面的命令以安装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站点 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;
}