使用Castle TypedFactory进行Owin应用程序配置

时间:2015-07-28 14:48:07

标签: .net castle-windsor asp.net-web-api2 owin castle

我有一个配置了Owin和Castle的WebAPI应用程序。该应用程序将托管在IIS上(所以我安装包Microsoft.Owin.Host.SystemWeb)

我想配置基于令牌的身份验证,并拥有一个自定义的OAuthAuthorizationServerProvider,它将使用Castle TypedFactoryFacility(我删除了提供的示例中的代码,因为它不会导致错误)。

这是我的Owin应用程序的启动类代码

    public class Startup {
    public void Configuration(IAppBuilder app)
    {
        HttpConfiguration config = new HttpConfiguration();
        config.MapHttpAttributeRoutes();
        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );

        var container = new WindsorContainer();

        //_windsorContainer.Install(FromAssembly.This());
        container.AddFacility<TypedFactoryFacility>();
        container.Register(Component.For<AuthorizationServerProvider>());
        config.Services.Replace(typeof(IHttpControllerActivator), new WindsorCompositionRoot(container));

        OAuthAuthorizationServerOptions oAuthServerOptions = new OAuthAuthorizationServerOptions()
        {
            AllowInsecureHttp = true,
            TokenEndpointPath = new PathString("/token"),
            AccessTokenExpireTimeSpan = TimeSpan.FromMinutes(15),
            Provider = container.Resolve<AuthorizationServerProvider>()
        };

        // Token Generation
        app.UseOAuthAuthorizationServer(oAuthServerOptions);
        app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());

        app.UseWebApi(config);

    } }

WindsorCompositionRoot是Mark Seemann提出的实现:http://blog.ploeh.dk/2012/10/03/DependencyInjectioninASP.NETWebAPIwithCastleWindsor/

当我尝试调试我的应用程序时,我收到以下错误:

  

找不到支持服务System.Threading.Tasks.Task的组件

这是相应的stacktrace

  

[ComponentNotFoundException:找不到支持服务System.Threading.Tasks.Task的组件]      Castle.MicroKernel.DefaultKernel.Castle.MicroKernel.IKernelInternal.Resolve(类型服务,IDictionary参数,IReleasePolicy策略)+106   Castle.Facilities.TypedFactory.TypedFactoryComponentResolver.Resolve(IKernelInternal kernel,IReleasePolicy scope)+307

     

Castle.Facilities.TypedFactory.Internal.TypedFactoryInterceptor.Resolve(IInvocation   调用)+256
  Castle.Facilities.TypedFactory.Internal.TypedFactoryInterceptor.Intercept(IInvocation   调用)+265 Castle.DynamicProxy.AbstractInvocation.Proceed()+484   Castle.Proxies.Func'2Proxy.Invoke(OAuthMatchEndpointContext arg)+174   Microsoft.Owin.Security.OAuth.OAuthAuthorizationServerProvider.MatchEndpoint(OAuthMatchEndpointContext   上下文)+59   Microsoft.Owin.Security.OAuth.d__0.MoveNext()+693   System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务   任务)+93
  System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务   任务)+52 System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()   +24 Microsoft.Owin.Security.Infrastructure.d__0.MoveNext()+664 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task   任务)+93
  System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务   任务)+52 System.Runtime.CompilerServices.TaskAwaiter.GetResult()+21   Microsoft.Owin.Host.SystemWeb.IntegratedPipeline.d__5.MoveNext()   +287 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务   任务)+93
  System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务   任务)+52 System.Runtime.CompilerServices.TaskAwaiter.GetResult()+21   Microsoft.Owin.Host.SystemWeb.IntegratedPipeline.d__2.MoveNext()   +272 System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()+22 Microsoft.Owin.Host.SystemWeb.Infrastructure.ErrorState.Rethrow()+33 Microsoft.Owin.Host.SystemWeb.IntegratedPipeline.StageAsyncResult.End(IAsyncResult)   ar)+150
  Microsoft.Owin.Host.SystemWeb.IntegratedPipeline.IntegratedPipelineContext.EndFinalWork(IAsyncResult的   ar)+42
  System.Web.AsyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()   +415 System.Web.HttpApplication.ExecuteStep(IExecutionStep step,Boolean&amp; completedSynchronously)+155

如果我没有将TypedFactoryFacility添加到我的容器中,我的项目工作没有那个错误......

为什么Castle会在那个地方注入一个TypedFactory?我该怎么做才能避免这个错误?

2 个答案:

答案 0 :(得分:1)

我将此作为答案发布,但您可能需要调查一些途径。

我在使用TypedFactoryFacility时遇到了一些不好的意外,因为它试图解析任何Func<>和/或Lazy&lt;&gt;类型属性或类型化工厂的构造函数参数。您可能在城堡试图解决的组件中使用其中一种类型。

如果是这种情况,您可能需要明确配置分辨率,如Typed factory facility页面所示。另一种选择是remove the DelegateFactory from the container

答案 1 :(得分:1)

基于Samy和Phil Degenhardt的提示,这里有一种强制城堡不填充OnMatchEndpoint属性并让它工作的方法:

container.Register(Component.For<AuthorizationServerProvider>()
            .PropertiesIgnore((m, p) => p.PropertyType == typeof(Func<OAuthMatchEndpointContext, Task>)));