2010-06-28 25 views
15

Được coi là biểu mẫu không hợp lệ để đăng ký thành phần ở Windsor mà không chỉ định giao diện? tức làBạn có thể đăng ký thành phần ở Windsor mà không cần chỉ định giao diện không?

container.Register(Component.For<MyClass>().LifeStyle.Transient); 

như trái ngược với ...

container.Register(Component.For<IMyClass>().ImplementedBy<MyClass>().LifeStyle.Transient); 

Tôi hiểu những lợi ích của mã hóa với một giao diện chứ không phải là một thực hiện cụ thể tuy nhiên chúng tôi thấy rằng bây giờ chúng tôi có rất nhiều giao diện nhiều trong số đó là trên các lớp học thực tế sẽ chỉ có một lần thực hiện.

Trả lời

23

Có, bạn có thể đăng ký thành phần mà không cần giao diện của chúng, nhưng không phải vì lý do bạn cung cấp.

phụ thuộc bê tông

Nó có thể xảy ra rằng các thành phần phụ thuộc vào lớp bê tông. Ví dụ, với các đối tượng Entity Framework nên có ObjectContext được chèn vào chúng. Đó là một lớp cụ thể vẫn cần phải được tiêm vì nó phải là được chia sẻ giữa một số người tiêu dùng.

Như vậy, do nhà xây dựng của người tiêu dùng như thế này:

public FooRepository(FooObjectContext objectContext) 

bạn sẽ cần phải cấu hình container như thế này:

container.Register(Component.For<FooObjectContext>()); 

Các FooRepository yêu cầu không có giao diện vì thế nó làm cho không có tên đăng ký lưu ý một giao diện (ngay cả khi có sẵn), nhưng bạn vẫn phải đăng ký lớp bê tông vì Windsor có thể chỉ giải quyết các loại được đăng ký rõ ràng.

giao diện chỉ với một thực hiện

Sau đó, những gì về giao diện chỉ với một thực hiện? Một lần nữa, người tiêu dùng quyết định các yêu cầu.

Hãy tưởng tượng rằng một người tiêu dùng có constructor này:

public Ploeh(IBar bar) 

Cách duy nhất lâu đài Windsor sẽ có thể giải quyết Ploeh là khi bạn đăng ký Ibar. Thậm chí nếu Bar là việc thực hiện duy nhất của Ibar, này sẽ không hoạt:

container.Register(Component.For<Bar>()); 

này không làm việc vì Ibar không bao giờ được đăng ký. Castle Windsor không quan tâm rằng Bar thực hiện IBar bởi vì nó không muốn cố gắng thông minh thay cho bạn. Bạn phải nói rõ ràng:

container.Register(Component.For<IBar>().ImplementedBy<Bar>()); 

bản đồ IBar to Bar.

Đăng ký cả hai giao diện và các loại bê tông

Sau đó những gì nếu bạn muốn để có thể giải quyết tất cả các kiểu dữ liệu cụ và giao diện?

Vấn đề với ví dụ trước là nó sẽ cho phép bạn giải quyết IBar, nhưng không cho phép Bar.

Bạn có thể sử dụng phương pháp Forward, hoặc quá tải multigeneric của For để chuyển tiếp đăng ký:

container.Register(Component.For<Bar, IBar>().ImplementedBy<Bar>()); 

này cho phép bạn giải quyết cả Bar và Ibar.

+2

một ví dụ khác sẽ là Bộ điều khiển trong ứng dụng MVC - bạn không cần phải tóm tắt chúng. –

+0

Có, Bộ điều khiển MVC là một ví dụ tốt hơn - tôi chỉ bị kẹt trong một số mã EF, vì vậy nó xuất hiện trong tâm trí của tôi trước tiên :) –

+0

Cảm ơn Mark nhưng nếu tôi là nhà phát triển tạo lớp Bar, tôi nên làm cho nó có giao diện IBar đơn giản để tôi có thể đăng ký tại Windsor thông qua giao diện? Tại sao không chỉ đơn giản là đăng ký Bar ở Windsor và làm cho Ploeh tiêu thụ Bar? –

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