c# - Windsor 不解析拦截的组件

标签 c# castle-windsor interceptor

谁能解释为什么这不起作用?如果您从 IFoo 的注册中删除拦截器并解析一个 Bar,您将得到一个 Foo(MyFoo 不为空)。但是有了拦截器, Foo 就不再解析了。

为什么?我怎么知道为什么它不能通过日志记录或跟踪来解决?

版本:

  • 城堡核心:3.2
  • 温莎城堡:3.2
  • .NET 4.5
  • C# 5

    using Castle.DynamicProxy;
    using Castle.MicroKernel.Registration;
    using Castle.Windsor;
    using System;
    
    namespace Sandbox
    {
    public interface IFooInterceptor : IInterceptor { }
    
    public interface IFoo
    {
        void Print();
    }
    
    public interface IBar
    {
        IFoo MyFoo { get; set; }
    }
    
    public class Foo : IFoo
    {
        public void Print()
        {
            Console.WriteLine("Print");
        }
    }
    
    public class FooInterceptor : IFooInterceptor, IInterceptor
    {
    
        public void Intercept(IInvocation invocation)
        {
            Console.WriteLine("Awesome");
            invocation.Proceed();
        }
    }
    
    public class Bar : IBar
    {
        public virtual IFoo MyFoo { get; set; }
    }
    
    class Program
    {
    
        static void Main(string[] args)
        {
            IWindsorContainer container = new WindsorContainer()
                .Register(
                    Component.For<IBar>().ImplementedBy<Bar>().LifestyleTransient(),
                    Component.For<IFoo>().ImplementedBy<Foo>().LifestyleTransient().Interceptors<IFooInterceptor>(),
                    Component.For<IFooInterceptor>().ImplementedBy<FooInterceptor>().LifestyleTransient()
                );
    
            var bar = container.Resolve<IBar>();
            var foo = container.Resolve<IFoo>();  // this isn't null
            bar.MyFoo.Print();                    // exception: bar.MyFoo is null
            Console.WriteLine("Done");
            Console.ReadLine();
        }
    
    }
    }
    

编辑:我刚刚发现(主要是偶然地)将拦截器配置从接口(interface)更改为具体类是可行的。但是,我正在注册拦截器及其接口(interface),因此对原始问题稍作修改:为什么接口(interface)规范会失败(默默地,不少于)?

最佳答案

CaSTLe 将属性作为可选依赖项处理,但它应该默认注入(inject)它们。但似乎与拦截器结合使用时,这些可选依赖项并未正确解析。

您可以做的是通过将 Bar 更改为使用构造函数注入(inject)来使依赖项成为必需项:

public class Bar : IBar
{
    public Bar(IFoo foo)
    {
        MyFoo = foo;
    }

    public virtual IFoo MyFoo { get; private set; }
}

或者使用明确标记为必需的Properties注册Bar:

Component.For<IBar>().ImplementedBy<Bar>().LifestyleTransient()
    .Properties(Prop‌​ertyFilter.RequireAll)

注意:在生产中你应该使用 PropertiesRequired 方法而不是 Properties 因为它现在已经过时了。

我还发现了这个似乎也相关的 github 问题:Bug - optional dependencies not provided

关于c# - Windsor 不解析拦截的组件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15534452/

相关文章:

c# - ServiceStack Redis获取结构始终返回默认值

c# - 如何在js文件中使用逗号分隔符加入t4元素?

c# - 仅使用代码在 IIS 外部使用 CaSTLe-Windsor 托管 WCF 服务

c# - 依赖注入(inject)和类继承

c# - 没有接口(interface)的 CaSTLe Windsor 拦截器?

c# - 为什么不尝试{} catch {}在C#中工作?

c# - 如何使用 C# API 将 BigQuery 行转换为 JSON?

java - 拦截器绑定(bind)不起作用

Angular 拦截器队列

c# - Web API - 拦截器 - 拦截异步 Controller 操作