IHttpController
데코레이터로 Web API 컨트롤러 ( 구현) 를 래핑하려고하는데 , 이렇게하면 Web API가 예외를 던집니다. 어떻게 든 실제 구현을 기대하기 때문입니다.
컨트롤러에 데코레이터를 적용하는 것은 MVC 컨트롤러에 성공적으로 적용하는 트릭이며 Web API에서도 동일하게 적용하고 싶습니다.
IHttpControllerActivator
장식 된 IHttpController
구현을 해결할 수 있는 사용자 지정 을 만들었습니다 . 다음은 제거 된 구현입니다.
public class CrossCuttingConcernHttpControllerActivator : IHttpControllerActivator {
private readonly Container container;
public CrossCuttingConcernHttpControllerActivator(Container container) {
this.container = container;
}
public IHttpController Create(HttpRequestMessage request,
HttpControllerDescriptor controllerDescriptor, Type controllerType)
{
var controller = (IHttpController)this.container.GetInstance(controllerType);
// Wrap the instance in one or multiple decorators. Note that in reality, the
// decorator is applied by the container, but that doesn't really matter here.
return new MyHttpControllerDecorator(controller);
}
}
내 데코레이터는 다음과 같습니다.
public class MyHttpControllerDecorator : IHttpController {
private readonly IHttpController decoratee;
public MyHttpControllerDecorator(IHttpController decoratee) {
this.decoratee = decoratee;
}
public Task<HttpResponseMessage> ExecuteAsync(
HttpControllerContext controllerContext,
CancellationToken cancellationToken)
{
// this decorator does not add any logic. Just the minimal amount of code to
// reproduce the issue.
return this.decoratee.ExecuteAsync(controllerContext, cancellationToken);
}
}
그러나 내 응용 프로그램을 실행하고을 요청하면 ValuesController
Web API가 다음을 던집니다 InvalidCastException
.
'WebApiTest.MyHttpControllerDecorator'유형의 개체를 'WebApiTest.Controllers.ValuesController'유형으로 캐스팅 할 수 없습니다.
Stacktrace :
at lambda_method(Closure , Object , Object[] )
at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.<>c__DisplayClass13.<GetExecutor>b__c(Object instance, Object[] methodParameters)
at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.Execute(Object instance, Object[] arguments)
at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.<>c__DisplayClass5.<ExecuteAsync>b__4()
at System.Threading.Tasks.TaskHelpers.RunSynchronously[TResult](Func`1 func, CancellationToken cancellationToken)
마치 Web API가 IHttpController
추상화를 제공하지만이를 건너 뛰고 구현 자체에 의존하는 것과 같습니다. 이것은 물론 종속성 반전 원칙을 심각하게 위반하고 추상화를 완전히 쓸모 없게 만듭니다. 그래서 나는 아마도 대신 뭔가 잘못하고있을 것입니다.
내가 뭘 잘못하고 있니? 내 API 컨트롤러를 어떻게 행복하게 꾸밀 수 있습니까?
ASP.NET Web API에서이 동작을 달성하는 자연스럽고 설계된 방법은 사용자 지정 메시지 처리기 / 위임 처리기를 사용하는 것입니다.
예를 들어 나는 이것을 DelegationHandler
제자리에 가지고 있습니다.
public class AuthenticationDelegationHandler : DelegatingHandler
{
protected override System.Threading.Tasks.Task<HttpResponseMessage>
SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
// I. do some stuff to create Custom Principal
// e.g.
var principal = CreatePrincipal();
...
// II. return execution to the framework
return base.SendAsync(request, cancellationToken).ContinueWith(t =>
{
HttpResponseMessage resp = t.Result;
// III. do some stuff once finished
// e.g.:
// SetHeaders(resp, principal);
return resp;
});
}
그리고 이것은 구조에 그것을 주입하는 방법입니다.
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.MessageHandlers.Add(new AuthenticationDelegationHandler());
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다