編集した質問に応じて、基本的な考えを示します。
// Message types
class Message { }
class MessageA : Message { }
class MessageB : Message { }
とベースメッセージプロセッサ:あなたは、そのカスタムプロセッサに特定のメッセージタイプをバインドする必要があり
interface IMessageProcessor
{
void ProcessMessage(Message message);
}
abstract class MessageProcessor<TMessage> : IMessageProcessor
where TMessage : Message
{
protected abstract void ProcessMessage(TMessage message);
public void ProcessMessage(Message message)
{
ProcessMessage((TMessage)message);
}
}
メッセージの種類があることを
と仮定。上記のコードを使用すること、
[MessageProcessor(typeof(MessageA))]
class MessageAProcessor : MessageProcessor<MessageA>
{
protected override void ProcessMessage(MessageA message)
{
Console.WriteLine("Processing A message...");
}
}
[MessageProcessor(typeof(MessageB))]
class MessageBProcessor : MessageProcessor<MessageB>
{
protected override void ProcessMessage(MessageB message)
{
Console.WriteLine("Processing B message...");
}
}
ここではサンプルキューがあります:
// Mapping attribute
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
class MessageProcessorAttribute : Attribute
{
public MessageProcessorAttribute(Type messageType)
{
MessageType = messageType;
}
public Type MessageType { get; }
}
今、あなたは宣言することができメッセージプロセッサ:これは、カスタム属性を必要とする、つまり、いくつかのメタデータを使用して行うことができる
// Message queue
class MessageQueue
{
private readonly Queue<Message> messages;
public MessageQueue()
{
messages = new Queue<Message>();
}
public void PostMessage(Message message)
{
messages.Enqueue(message);
}
public void ProcessMessages()
{
while (messages.Any())
{
var message = messages.Dequeue();
var messageProcessor = GetMessageProcessorOrDefault(message);
messageProcessor?.ProcessMessage(message);
}
}
private IMessageProcessor GetMessageProcessorOrDefault(Message message)
{
var messageType = message.GetType();
var messageProcessorTypes = GetMessageProcessorTypes();
var messageProcessorType = messageProcessorTypes
.FirstOrDefault(mpt => mpt.GetCustomAttribute<MessageProcessorAttribute>()?.MessageType == messageType);
return messageProcessorType != null ? (IMessageProcessor)Activator.CreateInstance(messageProcessorType) : null;
}
private IEnumerable<Type> GetMessageProcessorTypes()
{
// TODO: scan assemblies to retrieve IMessageProcessor implementations
return new[]
{
typeof(MessageAProcessor),
typeof(MessageBProcessor)
};
}
}
このアプローチをDIコンテナと組み合わせて、プラグインベースのアプリケーション(メッセージタイプとプロセッサの数)を、その場所(同じアセンブリまたは複数のアセンブリ)が行うように構築できます関係なく。
更新。私はすべての子孫に型キャストを避けるためにいくつかのジェネリックを追加しました。
簡単な答え:これはできません。解決しようとしている実際の問題は何ですか? – Dennis
'ParentClass'のポイントは何ですか?あなたはそのタイプ、または子タイプを取得したいですか? – gobes
ゴブ:この質問のために、親クラスは実際にはあまりしません:)おそらくそれを残している可能性があります。 –