I have a AsyncCommandHandlerDecorator<TCommand> and LifetimeScopedCommandHandlerDecorator<TCommand> as shown below:
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);
}
}
}
and I register decorators like this:
container.RegisterSingleDecorator(
typeof(ICommandHandler<>),
typeof(LifetimeScopedCommandHandlerDecorator<>),
c => c.ImplementationType.Name.StartsWith("Async"));
container.RegisterSingleDecorator(
typeof(ICommandHandler<>),
typeof(AsyncCommandHandlerDecorator<>),
c => c.ImplementationType.Name.StartsWith("Async"));
But, when the async process attempt to invoke, I get this error:
Attempt by security transparent method
‘LifetimeScopedCommandHandlerDecorator`1.Handle(!0)’ to
access security critical method
‘SimpleInjector.SimpleInjectorLifetimeScopeExtensions.BeginLifetimeScope(SimpleInjector.Container)’
failed.
I tried to use SecurityCritical attribute on both LifetimeScopedCommandHandlerDecorator.Handle and AsyncCommandHandlerDecorator.Handle, but it didn’t help. Have you any idea please?
UPDATE:
The exception is of type MethodAccessException and here is the complete stack trace:
at MYNAMESPACE.LifetimeScopedCommandHandlerDecorator`1.Handle(TCommand
command)at MYNAMESPACE.AsyncCommandHandlerDecorator`1.<>c_DisplayClass1.b_0(Object
_)in C:\MYPROJECTPATH\AsyncCommandHandlerDecorator.cs:line 23at System.Threading.QueueUserWorkItemCallback.WaitCallback_Context(Object
state)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()
at System.Threading.ThreadPoolWorkQueue.Dispatch()
at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback()
UPDATE 2:
With or whitout SecurityCritical attribute, problem exists.
Finally, I found the answer (thanks to @Steven for his helps).
In my assembly, I have added
[SecurityTransparent]for some reasons. In the other hand, Simple Injector uses theThreadLocal<T>internally. And theThreadLocal<T>is attributed byHostProtection(SecurityAction.LinkDemand)and inLinkDemand‘s comment, we can read:That means actually the
ThreadLocal<T>class is aSecurityCriticalobject and we can not call aSecurityCriticalmethod by aSecurityTransparentone.