ASP.NET WebAPI 컨트롤러에 종속성을 주입하기 위해 IoC 컨테이너를 사용하여 성공한 사람이 있습니까? 나는 그것을 작동시킬 수없는 것 같습니다.
이것이 제가 지금하고있는 일입니다.
내 global.ascx.cs
:
public static void RegisterRoutes(RouteCollection routes)
{
// code intentionally omitted
}
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
IUnityContainer container = BuildUnityContainer();
System.Web.Http.GlobalConfiguration.Configuration.ServiceResolver.SetResolver(
t =>
{
try
{
return container.Resolve(t);
}
catch (ResolutionFailedException)
{
return null;
}
},
t =>
{
try
{
return container.ResolveAll(t);
}
catch (ResolutionFailedException)
{
return new System.Collections.Generic.List<object>();
}
});
System.Web.Mvc.ControllerBuilder.Current.SetControllerFactory(new UnityControllerFactory(container));
BundleTable.Bundles.RegisterTemplateBundles();
}
private static IUnityContainer BuildUnityContainer()
{
var container = new UnityContainer().LoadConfiguration();
return container;
}
내 컨트롤러 공장 :
public class UnityControllerFactory : DefaultControllerFactory
{
private IUnityContainer _container;
public UnityControllerFactory(IUnityContainer container)
{
_container = container;
}
public override IController CreateController(System.Web.Routing.RequestContext requestContext,
string controllerName)
{
Type controllerType = base.GetControllerType(requestContext, controllerName);
return (IController)_container.Resolve(controllerType);
}
}
종속성을 해결하기 위해 내 Unity 파일을 보지 않는 것 같으며 다음과 같은 오류가 발생합니다.
‘PersonalShopper.Services.WebApi.Controllers.ShoppingListController’유형의 컨트롤러를 작성하는 중에 오류가 발생했습니다. 컨트롤러에 매개 변수없는 공용 생성자가 있는지 확인하십시오.
System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create (HttpControllerContext controllerContext, Type controllerType) at System.Web.Http.Dispatcher.DefaultHttpControllerFactory.CreateInstance (HttpControllerContext controllerContext, HttpControllerDescriptor controllerDescriptor) at System.Web.Http.Dispatcher.DefaultHttpControllerFactory.CreateController (HttpControllerContext controllerContext, String controllerName) at System.Web.Http.Dispatcher.HttpControllerDispatcher.SendAsyncInternal (HttpRequestMessage request, CancellationToken cancelToken) at System.Web.Http.Dispatcher.HttpControllerDispatcher.SendAsync (HttpRequestMessage request, CancellationToken cancelToken)
컨트롤러는 다음과 같습니다.
public class ShoppingListController : System.Web.Http.ApiController
{
private Repositories.IProductListRepository _ProductListRepository;
public ShoppingListController(Repositories.IUserRepository userRepository,
Repositories.IProductListRepository productListRepository)
{
_ProductListRepository = productListRepository;
}
}
내 Unity 파일은 다음과 같습니다.
<unity xmlns="http://schemas.microsoft.com/practices/2010/unity">
<container>
<register type="PersonalShopper.Repositories.IProductListRepository, PersonalShopper.Repositories" mapTo="PersonalShopper.Implementations.MongoRepositories.ProductListRepository, PersonalShopper.Implementations" />
</container>
</unity>
이전 버전의 mvc에서는 컨트롤러 팩토리가 종속성을 해결해야한다는 것을 파악했기 때문에 컨트롤러 자체에 대한 등록이 없습니다.
내 컨트롤러 공장이 호출되지 않는 것 같습니다.
답변
그것을 알아 냈습니다.
들어 ApiControllers , MVC 4는 사용 System.Web.Http.Dispatcher.IHttpControllerFactory 및 System.Web.Http.Dispatcher.IHttpControllerActivator을 컨트롤러를 만들 수 있습니다. 이것들의 구현을 등록하는 정적 메소드가 없다면; 해결 될 때 mvc 프레임 워크는 종속성 해결 프로그램에서 구현을 찾고, 찾을 수없는 경우 기본 구현을 사용합니다.
다음을 수행하여 컨트롤러 종속성의 통합 해상도를 얻었습니다.
UnityHttpControllerActivator 생성 :
public class UnityHttpControllerActivator : IHttpControllerActivator
{
private IUnityContainer _container;
public UnityHttpControllerActivator(IUnityContainer container)
{
_container = container;
}
public IHttpController Create(HttpControllerContext controllerContext, Type controllerType)
{
return (IHttpController)_container.Resolve(controllerType);
}
}
해당 컨트롤러 활성화기를 Unity 컨테이너 자체의 구현으로 등록했습니다.
protected void Application_Start()
{
// code intentionally omitted
IUnityContainer container = BuildUnityContainer();
container.RegisterInstance<IHttpControllerActivator>(new UnityHttpControllerActivator(container));
ServiceResolver.SetResolver(t =>
{
// rest of code is the same as in question above, and is omitted.
});
}
답변
여기에 올바르게 작동하는 더 나은 솔루션이 있습니다.
http://www.asp.net/web-api/overview/extensibility/using-the-web-api-dependency-resolver
답변
이 모든 것을 분류하고 IDisposable 구성 요소를 제공하는 Unity.WebApi NuGet 패키지를 살펴볼 수 있습니다.
보다
http://nuget.org/packages/Unity.WebAPI
또는
http://www.devtrends.co.uk/blog/introducing-the-unity.webapi-nuget-package
답변
Microsoft는이를위한 패키지를 만들었습니다.
패키지 관리자 콘솔에서 다음 명령을 실행하십시오.
설치 패키지 Unity.AspNet.WebApi
Unity가 이미 설치되어있는 경우 App_Start \ UnityConfig.cs를 덮어 쓸지 묻는 메시지가 표시됩니다. 아니오라고 대답하고 계속하십시오.
다른 코드를 변경할 필요가 없으며 DI (통합 포함)가 작동합니다.
답변
나는 같은 오류가 있었고 몇 시간 동안 인터넷에서 해결책을 찾고있었습니다. 결국 WebApiConfig.Register를 호출하기 전에 Unity를 등록해야하는 것처럼 보였습니다. 내 global.asax는 이제 다음과 같습니다.
public class WebApiApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
UnityConfig.RegisterComponents();
AreaRegistration.RegisterAllAreas();
GlobalConfiguration.Configure(WebApiConfig.Register);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
}
나를 위해 이것은 Unity가 컨트롤러의 종속성을 해결할 수 없다는 문제를 해결했습니다.
답변
최근 RC에서 더 이상 SetResolver 메서드가 없다는 것을 알았습니다. 컨트롤러와 webapi에 대해 IoC를 모두 활성화하려면 Unity.WebApi (NuGet)와 다음 코드를 사용합니다.
public static class Bootstrapper
{
public static void Initialise()
{
var container = BuildUnityContainer();
GlobalConfiguration.Configuration.DependencyResolver = new Unity.WebApi.UnityDependencyResolver(container);
ControllerBuilder.Current.SetControllerFactory(new DefaultControllerFactory(new ControllerActivator()));
}
private static IUnityContainer BuildUnityContainer()
{
var container = new UnityContainer();
container.Configure(c => c.Scan(scan =>
{
scan.AssembliesInBaseDirectory();
scan.With<UnityConfiguration.FirstInterfaceConvention>().IgnoreInterfacesOnBaseTypes();
}));
return container;
}
}
public class ControllerActivator : IControllerActivator
{
IController IControllerActivator.Create(RequestContext requestContext, Type controllerType)
{
return GlobalConfiguration.Configuration.DependencyResolver.GetService(controllerType) as IController;
}
}
또한 IoC 마술을 위해 UnityConfiguration (NuGet에서도 제공)을 사용합니다. 😉
답변
답변을 읽은 후에도 여전히이 문제를 해결하기 위해 많은 작업을 수행해야했기 때문에 동료의 이익을 위해 여기에 있습니다. ASP.NET 4 Web API RC에서 수행해야 할 모든 작업입니다 (8 월 8 일 기준). ’13) :
- “Microsoft.Practices.Unity.dll”에 대한 참조 추가 [NuGet을 통해 추가 된 버전 3.0.0.0에 있습니다.]
- “Unity.WebApi.dll”에 대한 참조 추가 [NuGet을 통해 추가 된 버전 0.10.0.0에 있습니다.]
- Unity.WebApi 프로젝트에서 프로젝트에 추가 한 Bootstrapper.cs의 코드와 유사하게 컨테이너에 유형 매핑을 등록합니다.
- ApiController 클래스에서 상속하는 컨트롤러에서 매개 변수 유형을 매핑 된 유형으로 갖는 매개 변수화 된 생성자를 만듭니다.
자, 보라, 다른 코드 줄없이 생성자에 의존성을 주입 할 수 있습니다!
참고 : 이 블로그의 작성자가 작성한 댓글 중 하나에서이 정보를 얻었습니다 .