将 Unity 添加到 MVC WebApi 应用程序

Adding Unity to MVC WebApi app

大家好,我已经将 Unity 添加到 MVC 应用程序中。似乎 DI 正在使用应用程序的 MVC 部分,但我不明白为什么它不能使用应用程序的 API 部分。

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        config.MapHttpAttributeRoutes();

        config.Routes.MapHttpRoute(
            name:"DefaultApi",
            routeTemplate:"api/{controller}/{id}",
            defaults: new {id = RouteParameter.Optional}
        );

        config.Formatters.Add(new JsonMediaTypeFormatter());
        config.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling =
            Newtonsoft.Json.ReferenceLoopHandling.Ignore;
        config.Formatters.JsonFormatter.SerializerSettings.Formatting = Newtonsoft.Json.Formatting.None;
    }
}

public static class UnityMvcActivator
{
    /// <summary>
    /// Integrates Unity when the application starts.
    /// </summary>
    public static void Start(HttpConfiguration configuration) 
    {
        FilterProviders.Providers.Remove(FilterProviders.Providers.OfType<FilterAttributeFilterProvider>().First());
        FilterProviders.Providers.Add(new UnityFilterAttributeFilterProvider(UnityConfig.Container));

        DependencyResolver.SetResolver(new UnityDependencyResolver(UnityConfig.Container));

        // TODO: Uncomment if you want to use PerRequestLifetimeManager
        // Microsoft.Web.Infrastructure.DynamicModuleHelper.DynamicModuleUtility.RegisterModule(typeof(UnityPerRequestHttpModule));


    }

    /// <summary>
    /// Disposes the Unity container when the application is shut down.
    /// </summary>
    public static void Shutdown()
    {
        UnityConfig.Container.Dispose();
    }
}

    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new { controller = "Address", action = "Index", id = UrlParameter.Optional }
        );
    }

}

protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();
            GlobalConfiguration.Configure(WebApiConfig.Register);
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            BundleConfig.RegisterBundles(BundleTable.Bundles);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            UnityMvcActivator.Start(GlobalConfiguration.Configuration);


        }

我只是想让一个存储库在网络上工作 api 但我一直在获取

An error occurred when trying to create a controller of type 'AddressSearchController'. Make sure that the controller has a parameterless public constructor.",

这个错误。我看过一些关于这个的帖子。我已经尝试过了,但仍然无法正常工作。有人有什么建议吗?

public class AddressSearchController:_SimpleController<Address>
    {
        public AddressSearchController(IRepository<Address> addressRepository) : base(addressRepository)
        {

        }

        [HttpPost]
        [Route("api/AddressSearch/Search")]
        public IHttpActionResult Search([FromBody] AddressSearchDto addressSearchDto)
        {
            var addresses = new List<Address>()
            {
                CreateAddress(1,"Main St", 123),
                CreateAddress(2,"Main St", 124),
                CreateAddress(3,"Main St", 125),
            };

            return Ok(addresses);
        }

        static Address CreateAddress(int id,string street, int houseNumber)
        {
            return new Address()
            {
                Id = id,
                StreetName = street,
                HouseNumber = houseNumber
            };

        }
    }

     public static void RegisterTypes(IUnityContainer container)
    {
        RegisterInstances(container);
    }

    private static void RegisterInstances(IUnityContainer container)
    {
        container.RegisterType<IAddressContext, AddressContext>();
        container.RegisterType(typeof(IRepository<>), typeof(Repository<>));

    }

using System;
using Address_Tracker.Data.Context;
using Address_Tracker.Data.Context.Interfaces;
using Address_Tracker.Data.Repositories;
using Unity;

namespace Address_Tracker
{
    /// <summary>
    /// Specifies the Unity configuration for the main container.
    /// </summary>
    public static class UnityConfig
    {
        #region Unity Container
        private static Lazy<IUnityContainer> container =
          new Lazy<IUnityContainer>(() =>
          {
              var container = new UnityContainer();
              RegisterTypes(container);
              return container;
          });

        /// <summary>
        /// Configured Unity Container.
        /// </summary>
        public static IUnityContainer Container => container.Value;
        #endregion

        /// <summary>
        /// Registers the type mappings with the Unity container.
        /// </summary>
        /// <param name="container">The unity container to configure.</param>
        /// <remarks>
        /// There is no need to register concrete types such as controllers or
        /// API controllers (unless you want to change the defaults), as Unity
        /// allows resolving a concrete type even if it was not previously
        /// registered.
        /// </remarks>
        public static void RegisterTypes(IUnityContainer container)
        {
            RegisterInstances(container);
        }

        private static void RegisterInstances(IUnityContainer container)
        {
            container.RegisterType<IAddressContext, AddressContext>();
            container.RegisterType(typeof(IRepository<>), typeof(Repository<>));

        }
    }
}

你的 AddressSearchController 应该有一个默认构造函数,或者如果你没有默认/无参数构造函数,那么请在 AddressSearchController.[=22= 中传递接口而不是具体 类 ]

相信你可能会有这样的场景:

public class AddressSearchController : ApiController
{
    public AddressSearchController(SomeClassParameter obj)
    {  
        //some code 
    }
}

你真正想要的是以太这个:

public class AddressSearchController : ApiController 
{
    public AddressSearchController() // add default ctor
    {  
    }
    public AddressSearchController(SomeClassParameter obj)
    {  
        //some code 
    }
}

或者这个:

Unity

中为类型 SomeClassParameter 注册接口 ISomeClassParameter
protected void Application_Start()
{
    AreaRegistration.RegisterAllAreas();
    UnityConfig.RegisterComponents();                           // <----- Add this line
    GlobalConfiguration.Configure(WebApiConfig.Register);
    FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
    RouteConfig.RegisterRoutes(RouteTable.Routes);
    BundleConfig.RegisterBundles(BundleTable.Bundles);
}           

注册组件:

container.RegisterType<ISomeClassParameter , SomeClassParameter >();

并进行构造函数注入:

public class AddressSearchController : ApiController 
{
    public AddressSearchController(ISomeClassParameter obj)
    {  
        //some code 
    }
}

此外,请确保您有 WebApi version of Unity

我试过了,对我有用: