简单注入者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的调用...我不在乎拦截器是否拦截装饰器但是装饰应该被拦截