Ste*_*ven 7 c# dependency-injection decorator asp.net-web-api
我试图总结的Web API控制器(IHttpController带装饰的实现),但我这样做的时候,网页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);
}
}
Run Code Online (Sandbox Code Playgroud)
我的装饰师看起来像这样:
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);
}
}
Run Code Online (Sandbox Code Playgroud)
但是,当我运行我的应用程序并请求时ValuesController,Web API会抛出以下内容InvalidCastException:
无法将"WebApiTest.MyHttpControllerDecorator"类型的对象强制转换为"WebApiTest.Controllers.ValuesController".
堆栈跟踪:
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)
Run Code Online (Sandbox Code Playgroud)
就好像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;
});
}
Run Code Online (Sandbox Code Playgroud)
这是将其注入结构的方法:
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.MessageHandlers.Add(new AuthenticationDelegationHandler());
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4367 次 |
| 最近记录: |