Не совсем понятно зачем Вам нужна цепочка обязонностей, если для каждого типа сообщения выполняется строго один хендлер.
Как только Вы находите первый подходящий, Вы выходите из цикла
if (handler.CanHandle(socket, messageType, server))
{
handler.Handle(socket, webSocketMessage, server);
return;
}
Цепочка обязанностей, это по сути конвеер, по которому пройдет сообщение. Этот патерн хорош, что легко можно добавить новое условие обработчика для каких то поступающих данных. Например, первый хендлер расшифровать, второй отформатировать, третий залогировать и т.д. Для этого в каждом Вашем хендлере должен быть список разрешенных для обработки типов сообщений (чтобы каждый хендлер в конвеере знал какие ему нужно типы сообщений обработать) или в самом сообщении должно быть указано какими хендлерами его обрабатывать. Первый вариант получше.
Но у вас в каждом хендлере указано строго для одного типа. Поэтому можно было обойтись обычным свитчом.
public BaseHandler HandlerFactory(messageType)
switch(messageType)
{
case ChatMessage.Type:
retun new ChatHandler();
break;
case AuthMessage.Type:
retun new AuthHandler();
break;
...
}
}
var handler = Successor.HandlerFactory(messageType);
handler.Handle(socket, webSocketMessage, server);
Ну или на крайняк без этого фора
var handler = Handlers.FirstOdefault(x => x.CanHandle(socket, messageType, server));
if(handle != null)
handler.Handle(socket, webSocketMessage, server);
Или сделайте из списка хендлеров дикшинари
Handlers[messageType].Handle(socket, webSocketMessage, server);
Лично я бы использовал фабрику, только в данном случае без лишних созданий экземпляров, это выглядит проще и понятнее, добавить в нее еще один хендлер - это две строки кода.
Если Вас смущает статический класс, сделайте синглтон. По факту фабрики обычно и делают синглтонами.
Если везде смущает три параметра в конструкторе (socket, messageType, server), оберните их в фасад
class HandlerParam
{
public IWebSocketConnection socket { get; set; }
public string webSocketMessage { get; set; }
public IServer server { get; set; }
}
var handlerParam = new HandlerParam
{
...
}
handler.Handle(handlerParam);