1

我有一个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)”失败。

我尝试在and上使用SecurityCritical属性,但没有帮助。请问你有什么想法吗?LifetimeScopedCommandHandlerDecorator.HandleAsyncCommandHandlerDecorator.Handle

更新:

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

在 MYNAMESPACE.LifetimeScopedCommandHandlerDecorator`1.Handle(TCommand 命令)

在 MYNAMESPACE.AsyncCommandHandlerDecorator`1.<>c_ DisplayClass1.b _0(Object _)

   in C:\MYPROJECTPATH\AsyncCommandHandlerDecorator.cs:line 23 

在 System.Threading.QueueUserWorkItemCallback.WaitCallback_Context(对象状态)

在 System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext,ContextCallback 回调,对象状态,布尔值 preserveSyncCtx)

在 System.Threading.ExecutionContext.Run(ExecutionContext executionContext,ContextCallback 回调,对象状态,布尔值 preserveSyncCtx)

在 System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem()

在 System.Threading.ThreadPoolWorkQueue.Dispatch()

在 System.Threading._ThreadPoolWaitCallback.PerformWaitCallback()

更新 2:

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

4

1 回答 1

1

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

直接调用者必须被授予指定的权限不要在 .NET 框架中使用 4 . 改为完全信任使用System.Security.SecurityCriticalAttribute;对于部分信任,请使用System.Security.Permissions.SecurityAction.Demand.

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

于 2012-11-29T13:15:11.470 回答