5

これが機能しない理由を誰か説明できますか? IFoo の登録からインターセプターを削除して Bar を解決すると、Foo が得られます (MyFoo は null ではありません)。しかし、インターセプターを使用すると、Foo は解決されなくなります。

なんで?ロギングまたはトレースによって解決されない理由を確認するにはどうすればよいですか?

バージョン:

  • Castle.Core: 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または、明示的に必須とマークされた Bar を登録します。

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

注:現在は廃止されているため、本番環境では のPropertiesRequired代わりに メソッドを使用する必要があります。Properties

関連するように思われるこのgithubの問題も見つけました:バグ - オプションの依存関係が提供されていません

于 2013-03-21T08:17:43.037 に答える