使用 Castle TypedFactory 配置 Owin 应用程序
Owin application configuration with Castle TypedFactory
我有一个配置了 Owin 和 Castle 的 WebAPI 应用程序。该应用程序将托管在 IIS 上(所以我安装包 Microsoft.Owin.Host.SystemWeb)
我想配置一个基于令牌的身份验证,并有一个自定义的 OAuthAuthorizationServerProvider,它将使用 Castle TypedFactoryFacility(我在提供的示例中删除了该代码,因为它不会导致错误)。
这是我的 Owin 应用程序的启动 class 代码
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/
当我尝试调试我的应用程序时,出现以下错误:
No component for supporting the service System.Threading.Tasks.Task was found
这里是相应的堆栈跟踪
[ComponentNotFoundException: No component for supporting the service System.Threading.Tasks.Task was found]
Castle.MicroKernel.DefaultKernel.Castle.MicroKernel.IKernelInternal.Resolve(Type service, IDictionary arguments, IReleasePolicy policy) +106
Castle.Facilities.TypedFactory.TypedFactoryComponentResolver.Resolve(IKernelInternal kernel, IReleasePolicy scope) +307
Castle.Facilities.TypedFactory.Internal.TypedFactoryInterceptor.Resolve(IInvocation
invocation) +256
Castle.Facilities.TypedFactory.Internal.TypedFactoryInterceptor.Intercept(IInvocation
invocation) +265 Castle.DynamicProxy.AbstractInvocation.Proceed() +484
Castle.Proxies.Func'2Proxy.Invoke(OAuthMatchEndpointContext arg) +174
Microsoft.Owin.Security.OAuth.OAuthAuthorizationServerProvider.MatchEndpoint(OAuthMatchEndpointContext
context) +59
Microsoft.Owin.Security.OAuth.d__0.MoveNext() +693
System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task
task) +93
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task
task) +52 System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
+24 Microsoft.Owin.Security.Infrastructure.d__0.MoveNext() +664 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task
task) +93
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task
task) +52 System.Runtime.CompilerServices.TaskAwaiter.GetResult() +21
Microsoft.Owin.Host.SystemWeb.IntegratedPipeline.d__5.MoveNext()
+287 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task
task) +93
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task
task) +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& completedSynchronously) +155
如果我不将 TypedFactoryFacility 添加到我的容器中,我的项目工作时不会出现该错误...
为什么 Castle 会在那个地方注入 TypedFactory?我该怎么做才能避免该错误?
我将此作为答案发布,但这是您可能想要调查的一些途径。
我在使用 TypedFactoryFacility
时遇到了一些糟糕的惊喜,因为它试图解析任何 Func<>
and/or Lazy<> 类型 属性 或构造函数类型化工厂的参数。您的组件中可能有城堡试图解析的这些类型之一。
如果是这种情况,您可能需要明确配置分辨率,如 Typed factory facility page. An alternative is to remove the DelegateFactory
from the container
中所示
根据 Samy 和 Phil Degenhardt 的提示,这是一种强制城堡不填充 OnMatchEndpoint 属性 并使其工作的方法:
container.Register(Component.For<AuthorizationServerProvider>()
.PropertiesIgnore((m, p) => p.PropertyType == typeof(Func<OAuthMatchEndpointContext, Task>)));
我有一个配置了 Owin 和 Castle 的 WebAPI 应用程序。该应用程序将托管在 IIS 上(所以我安装包 Microsoft.Owin.Host.SystemWeb)
我想配置一个基于令牌的身份验证,并有一个自定义的 OAuthAuthorizationServerProvider,它将使用 Castle TypedFactoryFacility(我在提供的示例中删除了该代码,因为它不会导致错误)。
这是我的 Owin 应用程序的启动 class 代码
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/
当我尝试调试我的应用程序时,出现以下错误:
No component for supporting the service System.Threading.Tasks.Task was found
这里是相应的堆栈跟踪
[ComponentNotFoundException: No component for supporting the service System.Threading.Tasks.Task was found] Castle.MicroKernel.DefaultKernel.Castle.MicroKernel.IKernelInternal.Resolve(Type service, IDictionary arguments, IReleasePolicy policy) +106 Castle.Facilities.TypedFactory.TypedFactoryComponentResolver.Resolve(IKernelInternal kernel, IReleasePolicy scope) +307
Castle.Facilities.TypedFactory.Internal.TypedFactoryInterceptor.Resolve(IInvocation invocation) +256
Castle.Facilities.TypedFactory.Internal.TypedFactoryInterceptor.Intercept(IInvocation invocation) +265 Castle.DynamicProxy.AbstractInvocation.Proceed() +484 Castle.Proxies.Func'2Proxy.Invoke(OAuthMatchEndpointContext arg) +174 Microsoft.Owin.Security.OAuth.OAuthAuthorizationServerProvider.MatchEndpoint(OAuthMatchEndpointContext context) +59 Microsoft.Owin.Security.OAuth.d__0.MoveNext() +693 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +93
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +52 System.Runtime.CompilerServices.TaskAwaiter`1.GetResult() +24 Microsoft.Owin.Security.Infrastructure.d__0.MoveNext() +664 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +93
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +52 System.Runtime.CompilerServices.TaskAwaiter.GetResult() +21 Microsoft.Owin.Host.SystemWeb.IntegratedPipeline.d__5.MoveNext() +287 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +93
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +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& completedSynchronously) +155
如果我不将 TypedFactoryFacility 添加到我的容器中,我的项目工作时不会出现该错误...
为什么 Castle 会在那个地方注入 TypedFactory?我该怎么做才能避免该错误?
我将此作为答案发布,但这是您可能想要调查的一些途径。
我在使用 TypedFactoryFacility
时遇到了一些糟糕的惊喜,因为它试图解析任何 Func<>
and/or Lazy<> 类型 属性 或构造函数类型化工厂的参数。您的组件中可能有城堡试图解析的这些类型之一。
如果是这种情况,您可能需要明确配置分辨率,如 Typed factory facility page. An alternative is to remove the DelegateFactory
from the container
根据 Samy 和 Phil Degenhardt 的提示,这是一种强制城堡不填充 OnMatchEndpoint 属性 并使其工作的方法:
container.Register(Component.For<AuthorizationServerProvider>()
.PropertiesIgnore((m, p) => p.PropertyType == typeof(Func<OAuthMatchEndpointContext, Task>)));