2008-11-17 27 views
6

Tôi có một ứng dụng bao gồm nhiều hội đồng khác nhau, một trong số đó nắm giữ các giao diện khác nhau mà các lớp tuân theo và theo đó các lớp giao tiếp qua các biên giới lắp ráp. Có một số lớp học kích hoạt các sự kiện và một số sự kiện quan tâm đến những sự kiện này.C# Thực hành tốt nhất: Bộ điều khiển sự kiện tập trung hoặc không

Câu hỏi của tôi như sau: thực tiễn tốt là triển khai EventConsolidator trung tâm của một số loại? Điều này sẽ được đánh giá cao, vì nó sẽ cần phải biết tất cả các lớp (hoặc ít nhất là giao diện) ném một sự kiện, và mọi người tiêu dùng của một sự kiện sẽ cần phải có một tham chiếu đến EventConsolidator để đăng ký.

Hiện tại tôi có tình huống mà lớp A biết lớp B (nhưng không phải C), lớp B biết lớp C, v.v. Sau đó, nếu C kích hoạt sự kiện B cần nhặt nó lên và kích hoạt sự kiện riêng của nó để cho A để đáp ứng. Những loại dây chuyền này có thể khá dài, và có thể là B chỉ quan tâm đến sự kiện để vượt qua nó. Tôi không muốn A biết về C mặc dù, vì điều đó sẽ phá vỡ đóng gói.

Thực tiễn tốt trong tình huống này là gì? Tập trung các sự kiện, hoặc cười và mang nó và xác định các sự kiện trong mỗi lớp trung gian? Hoặc các tiêu chí để đưa ra quyết định là gì? Cảm ơn!

Chỉnh sửa: Here là một câu hỏi khác về cơ bản giống nhau.

Trả lời

8

Bạn có thể tự đặt sự kiện vào giao diện, để A không cần biết trực tiếp về C, nhưng chỉ cần có sự kiện liên quan. Tuy nhiên, có lẽ bạn có nghĩa là trường hợp của A không có một trường hợp của C ...

Tôi sẽ cố gắng tránh xa một hệ thống sự kiện tập trung. Nó có khả năng làm cho thử nghiệm khó khăn hơn, và giới thiệu khớp nối chặt chẽ như bạn nói.

Một mẫu đáng biết là làm cho proxy sự kiện trở nên đơn giản.Nếu B chỉ hiển thị một sự kiện để ủy quyền nó cho C, bạn có thể làm:

public event FooHandler Foo 
{ 
    add 
    { 
     c.Foo += value; 
    } 
    remove 
    { 
     c.Foo -= value; 
    } 
} 

Bằng cách đó, việc ủy ​​quyền đăng ký/hủy đăng ký thay vì hành động tăng sự kiện. Điều này có ảnh hưởng đến tính đủ điều kiện của GC, tất nhiên - điều này có thể mang lại lợi ích hay không, tùy thuộc vào tình huống. Đáng suy nghĩ về mặc dù.

+0

Cảm ơn Jon, luôn hữu ích như mọi khi! Đó là những gì tôi đang tìm kiếm trong trường hợp này, cổ vũ. –

+4

Một lời cảnh cáo. Nó có thể rất khó hiểu khi giá trị "người gửi" không phải là đối tượng mà bạn đã đăng ký. – Andreas

1

Tôi có thể cố gắng xoa bóp miền để mỗi lớp có thể trực tiếp phụ thuộc vào nguồn sự kiện thích hợp. Những gì tôi có nghĩa là đặt câu hỏi tại sao không biết về C? Có lẽ một D đang chờ xuất hiện?

Là một phương pháp thay thế, bạn có thể xem xét kiến ​​trúc môi giới sự kiện. Nó có nghĩa là các nhà quan sát không biết trực tiếp về nguồn gốc. Đây là một thú vị video.

1

này sẽ được đánh cùng, vì nó sẽ cần phải biết mỗi lớp

Tôi nghĩ rằng bạn đã trả lời câu hỏi của riêng bạn nếu bạn xem xét khớp nối đó là xấu! Việc truyền các sự kiện thông qua một chuỗi các trình xử lý tiềm năng là một mô hình khá phổ biến trong nhiều môi trường; Nó có thể không phải là cách tiếp cận hiệu quả nhất, nhưng nó tránh được sự phức tạp mà cách tiếp cận được gợi ý của bạn sẽ liên quan.

Một cách tiếp cận khác mà bạn có thể thực hiện là sử dụng bộ điều phối thư. Điều này liên quan đến việc sử dụng định dạng thông báo chung (hoặc ít nhất là một định dạng tiêu đề thư chung) để biểu diễn các sự kiện và sau đó đặt các thông điệp đó vào hàng đợi. Điều phối viên sau đó chọn từng sự kiện đó lần lượt (hoặc dựa trên một số ưu tiên) và định tuyến chúng trực tiếp đến trình xử lý yêu cầu. Mỗi trình xử lý phải được đăng ký với điều phối viên khi khởi động.

Một thông báo trong trường hợp này có thể chỉ đơn giản là một lớp học với một vài trường cụ thể khi bắt đầu. Thông điệp cụ thể có thể chỉ đơn giản là một đạo hàm, hoặc bạn có thể truyền dữ liệu cụ thể cho thông điệp của mình dưới dạng tham số 'đối tượng' cùng với tiêu đề thư.

6

Những gì bạn có thể thử là sử dụng sự kiện môi giới của NInject hoặc Unity Application Block.

này cho phép bạn, ví dụ:

[Publish("foo://happened")] 
public event EventHandler<FooArgs> FooHappened; 

[Subscribe("foo://happened")] 
public void Foo_Happened(object sender, FooArgs args) 
{ } 

Nếu cả hai đối tượng được tạo ra thông qua các thùng chứa các sự kiện sẽ được nối tự động.

1

Bạn có thể xem đối tượng EventBroker trong mẫu M $ và thực hành lib nếu bạn muốn các sự kiện tập trung.

Cá nhân tôi nghĩ tốt hơn là suy nghĩ về kiến ​​trúc của bạn thay vì mặc dù chúng tôi sử dụng EventBroker ở đây, không có mã mới nào của chúng tôi sử dụng nó và chúng tôi hy vọng sẽ loại bỏ nó trong một ngày nắng.

0

chúng tôi có riêng thực hiện môi giới sự kiện của chúng tôi (mã nguồn mở) Hướng dẫn tại địa chỉ: http://sourceforge.net/apps/mediawiki/bbvcommon/index.php?title=Event_Broker

Và một phân tích hiệu suất tại địa chỉ: www.planetgeek.ch/2009/07/12/event-broker-performance/

Ưu điểm so với CAB: - khai thác gỗ tốt hơn - hỗ trợ mở rộng - tốt hơn xử lý lỗi - xử lý mở rộng (UI, Background chủ đề, ...) và một số chi tiết tôi không thể nhớ ngay bây giờ.

Chúc mừng, Urs

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