Bạn cũng có thể sử dụng một số loại khung công tác IoC, như Spring.NET, để chèn từ điển. Bằng cách này, nếu bạn nhận được một loại tin nhắn mới, bạn không cần phải biên dịch lại trung tâm này - chỉ cần thay đổi một tập tin cấu hình.
Ví dụ dài chờ đợi:
Tạo một ứng dụng giao diện điều khiển mới, được đặt tên Ví dụ, và thêm điều này:
using System;
using System.Collections.Generic;
using Spring.Context.Support;
namespace Example
{
internal class Program
{
private static void Main(string[] args)
{
MessageBroker broker = (MessageBroker) ContextRegistry.GetContext()["messageBroker"];
broker.Dispatch(null, new Type1EventArgs());
broker.Dispatch(null, new Type2EventArgs());
broker.Dispatch(null, new EventArgs());
}
}
public class MessageBroker
{
private Dictionary<Type, object> handlers;
public Dictionary<Type, object> Handlers
{
get { return handlers; }
set { handlers = value; }
}
public void Dispatch<T>(object sender, T e) where T : EventArgs
{
object entry;
if (Handlers.TryGetValue(e.GetType(), out entry))
{
MessageHandler<T> handler = entry as MessageHandler<T>;
if (handler != null)
{
handler.HandleMessage(sender, e);
}
else
{
//I'd log an error here
Console.WriteLine("The handler defined for event type '" + e.GetType().Name + "' doesn't implement the correct interface!");
}
}
else
{
//I'd log a warning here
Console.WriteLine("No handler defined for event type: " + e.GetType().Name);
}
}
}
public interface MessageHandler<T> where T : EventArgs
{
void HandleMessage(object sender, T message);
}
public class Type1MessageHandler : MessageHandler<Type1EventArgs>
{
public void HandleMessage(object sender, Type1EventArgs args)
{
Console.WriteLine("Type 1, " + args.ToString());
}
}
public class Type2MessageHandler : MessageHandler<Type2EventArgs>
{
public void HandleMessage(object sender, Type2EventArgs args)
{
Console.WriteLine("Type 2, " + args.ToString());
}
}
public class Type1EventArgs : EventArgs {}
public class Type2EventArgs : EventArgs {}
}
Và một file app.config:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<sectionGroup name="spring">
<section name="context" type="Spring.Context.Support.ContextHandler, Spring.Core"/>
<section name="objects" type="Spring.Context.Support.DefaultSectionHandler, Spring.Core"/>
</sectionGroup>
</configSections>
<spring>
<context>
<resource uri="config://spring/objects"/>
</context>
<objects xmlns="http://www.springframework.net">
<object id="messageBroker" type="Example.MessageBroker, Example">
<property name="handlers">
<dictionary key-type="System.Type" value-type="object">
<entry key="Example.Type1EventArgs, Example" value-ref="type1Handler"/>
<entry key="Example.Type2EventArgs, Example" value-ref="type2Handler"/>
</dictionary>
</property>
</object>
<object id="type1Handler" type="Example.Type1MessageHandler, Example"/>
<object id="type2Handler" type="Example.Type2MessageHandler, Example"/>
</objects>
</spring>
</configuration>
Output:
Type 1, Example.Type1EventArgs
Type 2, Example.Type2EventArgs
No handler defined for event type: EventArgs
Như bạn có thể thấy, MessageBroker
không biết về bất kỳ trình xử lý nào và trình xử lý không biết về MessageBroker
. Tất cả các bản đồ được thực hiện trong ứng dụng.tệp cấu hình, để nếu bạn cần xử lý một loại sự kiện mới, bạn có thể thêm nó vào tệp cấu hình. Điều này đặc biệt tốt nếu các nhóm khác đang định nghĩa các loại sự kiện và trình xử lý - chúng có thể biên dịch nội dung của chúng trong dll, bạn thả nó vào triển khai của mình và chỉ cần thêm ánh xạ.
Từ điển có giá trị của đối tượng kiểu thay vì MessageHandler<>
vì trình xử lý thực không thể được truyền tới MessageHandler<EventArgs>
, vì vậy tôi phải hack xung quanh một chút. Tôi nghĩ rằng giải pháp vẫn còn sạch sẽ, và nó xử lý các lỗi ánh xạ tốt. Lưu ý rằng bạn cũng sẽ cần phải tham khảo Spring.Core.dll trong dự án này. Bạn có thể tìm thấy các thư viện here và tài liệu here. Các là có liên quan đến điều này. Cũng lưu ý, không có lý do gì bạn cần sử dụng Spring.NET cho điều này - ý tưởng quan trọng ở đây là tiêm phụ thuộc. Bằng cách nào đó, một cái gì đó sẽ cần phải nói cho các nhà môi giới để gửi tin nhắn của loại a đến x, và sử dụng một container IoC cho tiêm phụ thuộc là một cách tốt để có các nhà môi giới không biết về x, và ngược lại.
Một số khác SO câu hỏi liên quan đến IoC và DI:
Tôi thích các câu trả lời ở đây nhưng có thể một nơi nào đó như RefactorMyCode.com có thể là một nơi tốt hơn cho nó. Việc mọi người đăng mã trong phản hồi của họ trên trang web đó dễ dàng hơn một chút. –
Ok, tôi đã đăng ví dụ, kiểm tra xem nó ra –