2013-03-20 15 views
5

これはなぜ動作しないのか誰にも説明できますか?インターセプタをIFooの登録から削除してBarを解決すると、Foo(MyFooはnullではありません)を取得します。しかし、インターセプタでは、Fooはもう解決しません。ウィンザーは傍受されたコンポーネントを解決していません

なぜですか?ロギングやトレースを介して解決できない理由をどうすればわかりますか?

バージョン:

  • Castle.Core:3.2
  • Castle.Windsor: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(); 
        } 
    
    } 
    } 
    

編集:私はちょうどインターフェイスからコンクリートクラスへのインターセプタ設定の変更が機能することを(たぶん、事故によって)見つけました。しかし、私はインターセプターとそのインターフェースを登録しているので、元の質問は少し修正されています。なぜインターフェース仕様が失敗するのですか?

+1

は、私はまた、関連するように見えたこのgithubの問題を発見しました。 – Amy

+1

これはバグのようです。所有権はオプションですが、デフォルトでは記入する必要がありますが、何らかの理由で傍受と競合します。もしあなたが 'Component.For ().ImplementedBy ().LifestyleTransient()。Properties(PropertyFilter.RequireAll)'で依存関係を必須にするならば、それも動作します。私はこの問題をgithub:https://github.com/castleproject/Windsor/issues/24で見つけました。これはこれに関連しています。 – nemesv

+0

@nemesv私はあなたが答えとして投稿できるので、質問に答えが残らないと思う。 Bar.MyFooをコンストラクタ引数として提供することでも問題は解決されます。 – Marwijn

答えて

2

城はプロパティをオプションの依存関係として扱いますが、デフォルトでそれを挿入する必要があります。しかし、インターセプタと組み合わせると、これらのオプションの依存関係は正しく解決されないようです。

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) 

注:中現在Propertiesの代わりにPropertiesRequiredメソッドを使用する必要があります。私はDynamicproxyタグの除去に反対Bug - optional dependencies not provided

関連する問題