临时(或最终)解决方案...
这就是我设法解决问题的方法。
首先,我实现了一个简单的 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");
}
}
我已经配置了IAuthenticationManager使用ComponentRegistration<T>.UseFactoryMethod,所以我实现了一个这样的扩展方法:
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()
它闻起来臭臭的...
顺便说一句,我不相信该解决方案的可靠性,因为除非您尝试在请求线程之外的另一个线程中解析组件,否则它应该可以工作。
可悲的是,这种解决方案应该在很多情况下都可能失败。如果您的代码实现了非阻塞 I/O,我希望尝试IAuthenticationManager从另一个线程注入在CallContext...
当我找到更好、更优雅的解决方案时,我仍然会期待其他答案。