大家好我已经为MVC应用添加了Unity。似乎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);
}
我只是想让一个存储库在web api中工作,但我一直在
尝试创建类型为&#39; AddressSearchController&#39;的控制器时发生错误。确保控制器具有无参数的公共构造函数。&#34;,
这个错误。我看过几篇有关此事的帖子。我已经尝试过它们仍然无法使用它。有没有人有任何建议?
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<>));
}
}
}
答案 0 :(得分:1)
您的AddressSearchController
应该有默认构造函数,或者如果您没有默认/无参数构造函数,那么请在AddressSearchController
中传递接口而不是具体类。
我相信你可能有这样的场景:
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
}
}
或者这个:
在ISomeClassParameter
SomeClassParameter
类型的界面Unity
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
我试了一下,它对我有用: