c# – 装饰ASP.NET Web API IHttpController
我正在尝试使用装饰器来包装Web API控制器(IHttpController实现),但是当我这样做时,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:
堆栈跟踪: 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中实现此行为的自然设计方式是使用
Custom Message Handlers / Delegation Handlers
例如,我确实有这个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()); (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |