暂时(或最终)解决方案...
这是我解决问题的方法。
首先,我实现了一个简单的OWIN中间件:
public sealed class WindsorMiddleware : OwinMiddleware
{
public WindsorMiddleware(OwinMiddleware next) : base(next)
{
}
public override async Task Invoke(IOwinContext context)
{
CallContext.LogicalSetData("owinContext", context);
await Next.Invoke(context);
CallContext.FreeNamedDataSlot("owinContext");
}
}
我已经使用 ComponentRegistration<T>.UseFactoryMethod
配置了 IAuthenticationManager
,所以我实现了一个扩展方法如下:
public static ComponentRegistration<TService> UseOwinComponentFactoryMethod<TService>(this ComponentRegistration<TService> registration)
where TService : class
{
return registration.UsingFactoryMethod
(
(kernel, componentModel, creationContext) =>
{
IOwinContext owinContext = CallContext.LogicalGetData("owinContext") as IOwinContext;
Contract.Assert(owinContext != null);
if (creationContext.RequestedType == typeof(IAuthenticationManager))
{
return (TService)owinContext.Authentication;
}
else
{
throw new NotSupportedException();
}
},
managedExternally: true
);
}
最后,我是这样注册
IAuthenticationManager
的:
Component.For<IAuthenticationManager>().UseOwinComponentFactoryMethod().LifestyleTransient()
有味道...
顺便说一下,我对这个解决方案的可靠性并不自信,因为它只有在尝试在与请求不同的线程中解析组件时才能正常工作。
遗憾的是,很多情况下这种解决方案都会失败。如果你的代码实现了非阻塞IO,我预计会试图从设置“owinContext”的线程之外的另一个线程中注入IAuthenticationManager
...
我仍然期待其他答案,同时寻找更好、更优雅的解决方案。
HttpContext.Current.GetOwinContext()
无法使用? - Phil Degenhardt