2013-03-20 25 views
5

Bất cứ ai có thể giải thích tại sao điều này không hoạt động? Nếu bạn loại bỏ các interceptor từ đăng ký của IFoo và giải quyết một Bar, bạn nhận được một Foo (MyFoo không phải là null). Nhưng với kẻ đánh chặn, Foo không giải quyết nữa.Windsor không giải quyết các thành phần bị chặn

Tại sao? Làm thế nào tôi có thể nói lý do tại sao nó sẽ không giải quyết thông qua đăng nhập hoặc truy tìm?

phiên bản:

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

Chỉnh sửa: Tôi chỉ tìm thấy (chủ yếu là do tai nạn) mà thay đổi cấu hình chặn từ giao diện đến một lớp bê tông hoạt động. Tuy nhiên, tôi đang đăng ký máy đánh chặn và giao diện của nó, do đó, câu hỏi ban đầu được sửa đổi một chút: tại sao đặc tả giao diện thất bại (âm thầm, không kém)?

+1

Tôi không đồng ý với việc loại bỏ các thẻ DynamicProxy. – Amy

+1

Dường như đây là lỗi. Proprieties là các phụ thuộc tùy chọn nhưng chúng phải được điền vào theo mặc định nhưng nó xung đột với việc chặn bằng cách nào đó. Nếu bạn làm cho sự phụ thuộc của bạn bắt buộc với 'Component.For () .ImplementedBy () .LifestyleTransient(). Properties (PropertyFilter.RequireAll)' nó cũng hoạt động. Tôi đã tìm thấy vấn đề này trên github: https://github.com/castleproject/Windsor/issues/24 mà cảm thấy liên quan đến điều này. – nemesv

+0

@nemesv Tôi nghĩ bạn có thể đăng câu trả lời đó để câu hỏi không được trả lời. Việc cung cấp Bar.MyFoo làm đối số hàm tạo cũng sẽ giải quyết vấn đề. – Marwijn

Trả lời

2

Castle xử lý các thuộc tính như phụ thuộc tùy chọn nhưng nó sẽ tiêm chúng theo mặc định. Nhưng có vẻ như kết hợp với các Bộ chặn nhiễu, các phụ thuộc tùy chọn này không được giải quyết chính xác.

gì bạn có thể làm bạn là để làm cho sự phụ thuộc của bạn cần bằng cách thay đổi Bar để sử dụng constructor tiêm:

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

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

Hoặc đăng ký Bar với Properties một cách rõ ràng được đánh dấu yêu cầu:

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

Lưu ý: trong sản xuất bạn nên sử dụng phương pháp PropertiesRequired thay vì Properties vì nó đã lỗi thời.

Tôi cũng đã tìm thấy vấn đề này github mà cũng dường như có liên quan: Bug - optional dependencies not provided

Các vấn đề liên quan