温莎不解析被截获的组件

本文关键字:组件 | 更新日期: 2023-09-27 18:04:52

谁能解释一下为什么这不起作用?如果你从IFoo的注册中删除拦截器并解析一个Bar,你会得到一个Foo (MyFoo不是null)。但是使用拦截器,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();
        }
    }
    }
    

编辑:我刚刚发现(主要是偶然的),改变拦截器配置从一个接口到一个具体的类工作。然而,我注册拦截器和它的接口,所以原来的问题稍微修改:为什么接口规范失败(无声的,不少于)?

温莎不解析被截获的组件

Castle将属性作为可选的依赖项处理,但默认情况下应该注入它们。但是,与拦截器结合在一起,这些可选的依赖项似乎没有正确解决。

你所能做的就是通过改变Bar来使用构造函数注入,使你的依赖成为必需的:

public class Bar : IBar
{
    public Bar(IFoo foo)
    {
        MyFoo = foo;
    }
    public virtual IFoo MyFoo { get; private set; }
}

Properties明确标记为必需的寄存器条:

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

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

我也发现了这个github问题,这似乎也相关:Bug -可选的依赖没有提供