我有一个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"));
但是,当异步进程尝试调用时,我收到此错误:
尝试安全透明方法 'LifetimeScopedCommandHandlerDecorator`1.Handle(!0)'来 访问安全关键方法 'SimpleInjector.SimpleInjectorLifetimeScopeExtensions.BeginLifetimeScope(SimpleInjector.Container)' 失败。
我尝试在SecurityCritical
和LifetimeScopedCommandHandlerDecorator.Handle
使用AsyncCommandHandlerDecorator.Handle
属性,但它没有帮助。你有什么想法吗?
更新
异常是MethodAccessException
类型,这里是完整的堆栈跟踪:
at MYNAMESPACE.LifetimeScopedCommandHandlerDecorator`1.Handle(TCommand 命令)
at MYNAMESPACE.AsyncCommandHandlerDecorator`1。&lt;&gt; c_ DisplayClass1.b _0(Object _)
in C:\MYPROJECTPATH\AsyncCommandHandlerDecorator.cs:line 23
at System.Threading.QueueUserWorkItemCallback.WaitCallback_Context(Object 国家)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext,ContextCallback callback,Object state,Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext,ContextCallback callback,Object state,Boolean preserveSyncCtx)
at System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem()
在System.Threading.ThreadPoolWorkQueue.Dispatch()
在System.Threading._ThreadPoolWaitCallback.PerformWaitCallback()
更新2:
使用或whitout SecurityCritical
属性,问题存在。
答案 0 :(得分:1)
最后,我找到了答案(感谢@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
对象,我们无法调用 SecurityCritical
< / strong> SecurityTransparent
一个方法。