Simple Injector异步生命周期作用域和安全异常



我有一个AsyncCommandHandlerDecorator<TCommand>LifetimeScopedCommandHandlerDecorator<TCommand>,如下所示:

public class AsyncCommandHandlerDecorator<TCommand> 
: ICommandHandler<TCommand> where TCommand : ICommand {
private readonly Func<ICommandHandler<TCommand>> _factory;
public AsyncCommandHandlerDecorator(Func<ICommandHandler<TCommand>> factory) {
_factory = factory;
}
[SecurityCritical]
// with or whitout SecurityCritical attribute, problem exists. 
public void Handle(TCommand command) {
ThreadPool.QueueUserWorkItem(_ => {
var handler = _factory();
handler.Handle(command);
});
}
}
// AND
public class LifetimeScopedCommandHandlerDecorator<TCommand>
: ICommandHandler<TCommand> where TCommand : ICommand {
private readonly Container _container;
private readonly Func<ICommandHandler<TCommand>> _factory;
public LifetimeScopedCommandHandlerDecorator(Container container,
Func<ICommandHandler<TCommand>> factory) {
_container = container;
_factory = factory;
}

[SecurityCritical]
// with or whitout SecurityCritical attribute, problem exists. 
public void Handle(TCommand command) {
using (_container.BeginLifetimeScope()) {
var handler = _factory();
handler.Handle(command);
}
}
}

我注册这样的装饰器:

container.RegisterSingleDecorator(
typeof(ICommandHandler<>),
typeof(LifetimeScopedCommandHandlerDecorator<>),
c => c.ImplementationType.Name.StartsWith("Async"));
container.RegisterSingleDecorator(
typeof(ICommandHandler<>),
typeof(AsyncCommandHandlerDecorator<>),
c => c.ImplementationType.Name.StartsWith("Async"));

但是,当异步进程尝试调用时,我会得到以下错误:

通过安全透明方法进行的尝试'LifetimeScopedCommandHandlerRecorder`1.Handle(!0)'到访问安全关键方法"SimpleInjector.SimpleInjectorLifetimeScopeExtensions.BeginLifetimeScope(SimpleInjecter.Container)"失败。

我尝试在LifetimeScopedCommandHandlerDecorator.HandleAsyncCommandHandlerDecorator.Handle上使用SecurityCritical属性,但没有帮助。你知道吗?

更新:

异常类型为MethodAccessException,这里是完整的堆栈跟踪:

MYNAMESPACE.LifetimeScopedCommandHandlerRecorder`1.Handle(TCommand命令)

位于MYNAMESPACE.AncCommandHandlerRecorder`1.<>c_DisplayClass1.b_0(对象_)

in C:MYPROJECTPATHAsyncCommandHandlerDecorator.cs:line 23 

位于System.Threading.QueueUserWorkItemCallback.WetCallback_Context(对象状态)

在System.Threading.ExecutionContext.RunInternal(ExecutionContext ExecutionContext,ContextCallback回调,Object state,Boolean preserveSyncCtx)

在System.Threading.ExecutionContext.Run(ExecutionContext ExecutionContext,ContextCallback回调,Object state,Boolean preserveSyncCtx)

位于System.Threading.QueueUserWorkItemCallback.System.ThreadPoolWorkItem.ExecuteWorkItem()

位于System.Threading.ThreadPoolWorkQueue.Dispatch()

位于System.Threading._ThreadPoolWaitCallback.PerformWaitCallback()

更新2:

有或没有SecurityCritical属性,则存在问题。

终于找到了答案(感谢@Steven的帮助)。在我的程序集中,由于某些原因,我添加了[SecurityTransparent]。另一方面,Simple Injector在内部使用ThreadLocal<T>。并且ThreadLocal<T>HostProtection(SecurityAction.LinkDemand)所归属,并且在LinkDemand的评论中,我们可以读取:

立即调用方必须被授予指定的权限请勿在.NET framework 4中使用。对于完全信任,请改用System.Security.SecurityCriticalAttribute;对于部分信任,请使用System.Security.Permissions.SecurityAction.Demand

这意味着实际上ThreadLocal<T>类是SecurityCritical对象,并且我们不能用SecurityTransparent方法来调用SecurityCritical

相关内容

  • 没有找到相关文章

最新更新