拦截器不工作,如何调试它们

时间:2015-08-07 00:05:48

标签: castle-windsor castle-dynamicproxy

我正在努力让Castle Windsor使用我指定的拦截器。

这是我的代码:

container = new WindsorContainer();
container.AddFacility<TypedFactoryFacility>();

container.Register(Castle.MicroKernel.Registration
   .Types
   .FromThisAssembly()
   .BasedOn<IInterceptor>()
   .Configure(x=>x.LifestyleTransient()));               

container.Register(Castle.MicroKernel.Registration
   .Types
   .FromAssemblyInThisApplication()
   .BasedOn<IImporter>()
   .Configure(x => x.Interceptors<LoggingInterceptor>().LifeStyle.Is(LifestyleType.Transient)));

container.Register(Component
  .For<IImporterFactory>()
  .AsFactory(c => c.SelectedWith(new ImporterFactoryComponentSelector()))
  .LifeStyle.Transient);

设置Castle Windsor之后,我得到了我需要的IImporter实现:

IImporterFactory importerFactory = container.Resolve<IImporterFactory>();
var test = importerFactory.Create(FileType.M3Availability);
test.ImportFile(fileName);

我期待在test.ImportFile(str)执行之前调用拦截器,但它不是

我在组件注册过程中出错了吗?

查看“容器”对象我可以看到我的所有对象都有正确的拦截器(见图)

Visual Studio watch window with container object

我在组件注册期间做错了什么? 我该怎么调试呢?

1 个答案:

答案 0 :(得分:1)

Windsor只能拦截虚拟方法和接口。在你的实例中,你试图解决具体的类型,而windsor不能装饰它们。

解决方案是使用接口注册IImporter,并将每个实例命名为具体实现的名称。

更新

WithServiceAllInterfaces应该注册所有接口而不是类。

.Named(c.Implementation.Name)应该使用具体类型的名称注册接口,以便您可以在选择器中使用具体类型的名称。

您需要在注册时更改内容:

container.Register(Castle.MicroKernel.Registration
    .Classes
    .FromAssemblyInThisApplication()
    .BasedOn<IImporter>()
    .WithServiceAllInterfaces()
    .Configure(c => 
        c.Interceptors<LoggingInterceptor>()
        .LifeStyle.Is(LifestyleType.Transient).Named(c.Implementation.Name)));

我在你的代码上尝试了这个,这很有用。