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)」へのアクセスに失敗しました。

との両方で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(Object state)で

System.Threading.ExecutionContext.RunInternal(ExecutionContext executeContext、ContextCallbackコールバック、オブジェクト状態、ブール値preserveSyncCtx)で

System.Threading.ExecutionContext.Run(ExecutionContext executeContext、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]、いくつかの理由で追加しました。一方、SimpleInjectorThreadLocal<T>内部で使用します。そして、これThreadLocal<T>はのコメントによるものHostProtection(SecurityAction.LinkDemand)であり、LinkDemand次のように読むことができます。

直接の発信者には、指定された権限が付与されている必要があります。.NETFramework4では使用しないでくださいSystem.Security.SecurityCriticalAttribute代わりに完全な信頼のために使用してください。部分的な信頼には、を使用しますSystem.Security.Permissions.SecurityAction.Demand

つまり、実際にはThreadLocal<T>クラスはオブジェクトであり、1つでメソッドをSecurityCritical呼び出すことはできません。SecurityCriticalSecurityTransparent

于 2012-11-29T13:15:11.470 に答える