5

谁能解释为什么这不起作用?如果你从 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();
        }
    
    }
    }
    

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

4

1 回答 1

2

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

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

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

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

Properties或者使用明确标记的 required 注册 Bar :

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

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

我还发现了这个似乎也相关的 github 问题:错误 - 未提供可选依赖项

于 2013-03-21T08:17:43.037 回答