2013-03-20 10 views
5

Czy ktoś może wyjaśnić, dlaczego to nie działa? Jeśli usuniesz przechwytywacz z rejestracji IFoo i rozwiążesz pasek, otrzymasz Foo (MyFoo nie ma wartości NULL). Ale z przechwytującym, Foo nie rozwiązuje więcej.Windsor nie rozwiązuje przechwytywanych komponentów

Dlaczego? Jak mogę określić, dlaczego nie zostanie rozwiązany przez rejestrowanie lub śledzenie?

Wersje:

  • 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(); 
        } 
    
    } 
    } 
    

Edit: Właśnie znalazłem (głównie przez przypadek), że zmiana konfiguracji przechwytywacza z interfejsu na konkretną klasę działa. Jednak rejestruję przechwytywacz i jego interfejs, więc pierwotne pytanie zostało nieco zmienione: dlaczego specyfikacja interfejsu zawodzi (cicho, nie mniej)?

+1

Nie zgadzam się z usunięciem tagu Dynamicproxy. – Amy

+1

Wygląda na to, że to błąd. Właściwości są opcjonalne, ale powinny być wypełnione domyślnie, ale w jakiś sposób są w konflikcie z przechwytywaniem. Jeśli uzależnisz swoją obowiązkową zależność od 'Component.Forum: () .ImplementedBy () .LifestyleTransient(). Właściwości (PropertyFilter.RequireAll)' to również działa. Znalazłem ten problem na github: https://github.com/castleproject/Windsor/issues/24, co jest związane z tym. – nemesv

+0

@nemesv Myślę, że możesz opublikować to jako odpowiedź, aby pytanie nie pozostało bez odpowiedzi. Podanie argumentu Bar.MyFoo jako argumentu konstruktora również rozwiąże problem. – Marwijn

Odpowiedz

2

Zamek obsługuje właściwości jako opcjonalne zależności, ale domyślnie powinien je wstrzykiwać. Ale wydaje się, że w połączeniu z Interceptorami te opcjonalne zależności nie są poprawnie rozwiązywane.

Co można zrobić, ty jest, aby Państwa Zależności wymagane przez zmianę Bar użyć konstruktora wtrysku:

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

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

Albo zarejestrować Bar z Properties wyraźnie oznaczone wymagane:

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

Uwaga: w produkcji należy używać metody PropertiesRequired zamiast Properties, ponieważ obecnie jest ona przestarzała.

Ja również znaleźć ten GitHub problem, który również wydawał istotne: Bug - optional dependencies not provided

Powiązane problemy