gpt4 book ai didi

c# - 装饰 ASP.NET Web API IHttpController

转载 作者:太空狗 更新时间:2023-10-29 20:24:10 24 4
gpt4 key购买 nike

我试图用装饰器包装 Web API Controller (IHttpController 实现),但是当我这样做时,Web API 抛出异常,因为不知何故它期待实际的实现。

将装饰器应用于 Controller 是我成功应用于 MVC Controller 的一个技巧,显然我喜欢在 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:

Unable to cast object of type 'WebApiTest.MyHttpControllerDecorator' to type '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)

就好像 Web API 为我们提供了 IHttpController 抽象但跳过它并仍然依赖于实现本身。这当然会严重违反依赖倒置原则,并使抽象完全无用。所以我可能做错了什么。

我做错了什么?如何愉快地装饰我的 API Controller ?

最佳答案

我想说的是,如何在 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;
});
}

这是将其注入(inject)结构的方法:

public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.MessageHandlers.Add(new AuthenticationDelegationHandler());

关于c# - 装饰 ASP.NET Web API IHttpController,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20444059/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com