MVC Web API和Unity用于依赖注入

时间:2015-11-09 17:03:13

标签: asp.net-mvc asp.net-web-api dependency-injection unity-container

我正在构建一组非常简单的控制器,我想将依赖项注入其中。

我的Web Api项目正在使用.net 4.5.1(vs2015),我正在使用Unity进行依赖注入(对于Unity来说真的很新)。

这就是我所做的:

  1. 新项目> ASP.Net web appliction> Web Api项目(无认证)
  2. 工具> Nuget包管理器>管理解决方案包... 搜索" Unity.MVC"并安装包。
  3. 我创建了以下接口和类:

    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");
        }
    }
    
  4. 在我的简单控制器中,我实现了这个:

        public class HomeController : Controller
        {
            IExample instance;
    
            public HomeController(IExample injected)
            {
                instance = injected;
            }
    
            public ActionResult Index()
            {
                ViewBag.Title = "Home Page";
    
                return View();
            }
        }
    

    我从Unity获得了这两个新添加的文件:

    enter image description here

    我将以下代码添加到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)"
       }
    }
    

    提前致谢!

2 个答案:

答案 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中使用依赖注入与统一使用以下步骤。

  1. 在Web API项目中安装Unity包。 转到Package manager console paste下面的命令以安装Unity

      Install-Package Unity.WebAPI -Version 5.3.0
    
  2. 安装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;
         }  
      }
    
  3. 在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();
       }
    
  4. 最后一步是将服务接口注入Web AIP控制器构造函数。

      public CategoryController(ICategoryService Iinject)
      {
        this._categoryServices= Iinject;
      }