SimpleInjector InterceptWith不适用于通过Assembly.LoadFrom进行注册

时间:2016-07-28 14:56:23

标签: c# simple-injector

简单注入者documentation有一个描述如何执行interception的部分。 interception extensions code snippet会将拦截器添加到与容器匹配的所有接口上,并与您指定的条件匹配。

我正在使用从Async Programming : Intercepting Asynchronous Methods Using Unity Interception借来的代码并将其调整为简单的注入器。我使用

将跟踪添加到容器中
container.InterceptWith<TracingInterceptor>(t => 
  t.Namespace == "mynamespace" && t.IsInterface);

如何使用Assembly.LoadFrom加载此拦截器扩展以使用容器注册?

var assemblies = 
    from file in new DirectoryInfo(pluginDir).GetFiles()
    where file.Name.StartsWith("Proj.Plugin.", StringComparison.CurrentCultureIgnoreCase)
    where file.Extension.ToLower() == ".dll"
    select Assembly.LoadFrom(file.FullName);

var registrations = (
    from assembly in assemblies 
    from type in assembly.GetTypes()
    where !type.IsAbstract
    where typeof(IFoo).IsAssignableFrom(type) || typeof(IBar).IsAssignableFrom(type)
    select Lifestyle.Scoped.CreateRegistration(type, container))
    .ToArray();

container.RegisterCollection<IFoo>(
    registrations.Where(r => typeof(IFoo).IsAssignableFrom(r.ImplementationType)));
container.RegisterCollection<IBar>(
    registrations.Where(r => typeof(IBar).IsAssignableFrom(r.ImplementationType)));

修改

在装配A中

public class FooCommand {
  ...
}
public interface ICommandHandler<TCommand> {
  Task Handle(TCommand command);
}
public class ValidationCommandHandlerDecorator<TCommand> : ICommandHandler<TCommand> {
  ...
}

在装配B中,参考装配A

public class FooCommandHandler<FooCommand> : ICommandHandler<FooCommand> {
  public async Task Handle(FooCommand command) {
    ...
  }
}

在程序集C中

public class TracingInterceptor : IInterceptor {
  ...
}

在装配D中,仅参考装配A和C

public static class Bootstrapper {
  private static Container _container;
  public static void Bootstrap() {
    ...
    var assemblies = from file in new DirectoryInfo(pluginDir).GetFiles()
      where (file.Name.StartsWith("assemblyB.", StringComparison.CurrentCultureIgnoreCase)) 
      where file.Extension.ToLower() == ".dll"
      select Assembly.LoadFrom(file.FullName);
    _container.Register(typeof(ICommandHandler<>), assemblies, Lifestyle.Scoped);

    _container.RegisterDecorator(typeof(ICommandHandler<>), typeof(ValidationCommandHandlerDecorator<>), Lifestyle.Scoped);

    _container.Register<IFoo, Foo>(Lifestyle.Scoped);

    _container.InterceptWith<TracingInterceptor>(t =>
      t.Namespace.StartsWith("NS.", StringComparison.CurrentCulture)
      && t.IsInterface);
  }
}

public class Foo : IFoo {
  public Foo(ICommandHandler<FooCommand> fooCommand) {
    _fooCommnad = fooCommand;
  }

  private readonly ICommandHandler<FooCommnad> _fooCommand;

  public async Task Bar() {
    await _fooCommand.Handle(new FooCommand());
  }
}

对Foo.Bar的调用是正确的intrercepted,但不是对ValidationCommandHandlerDecorator.Handle或FooCommandHandler.Handle的调用...我不在乎拦截器是否拦截装饰器但是装饰应该被拦截

0 个答案:

没有答案