İstemcinin sunucuya farklı komut türleri gönderebileceği ve belirli sonuçları alabileceği basit istemci-sunucu çözümü üzerinde çalışıyorum. Komutların farklı özellikleri olabilir. Sahip olmak istediğim, ele aldığı komutun türüne göre belirli bir komut işleyicisinin seçilebileceği bir mimaridir.Dökümünüzü daha iyi bir desenle değiştirin
public interface ICommand
{
}
public class CommandA: ICommand
{
public string CustomProperty { get; set; }
}
public class CommandB: ICommand
{
}
Her komut komutu işleme ve sonucu dönen sorumludur kendi CommandHandler vardır: şöyle temel altyapıyı oluşturdu.
public interface ICommandHandler
{
bool CanHandle(ICommand command);
IReply Handle(ICommand command);
}
public abstract class CommandHandlerBase<TCommand> : ICommandHandler
where TCommand : class, ICommand
{
public bool CanHandle(ICommand command)
{
return command is TCommand;
}
public IReply Handle(ICommand command)
{
return Handle(command as TCommand);
}
public abstract IReply Handle(TCommand command);
}
// Specific handler
public class CommandAHandler : CommandHandlerBase<CommandA>
{
public override IReply Handle(CommandA command)
{
//handling command and returning result
return null;
}
}
Ben de sonucu uygun işleyicisi seçme ve dönen sorumlu bir sınıf yarattı: Hepsi CommandHandlerBaseClass devralan Ben CommandHandlerBase sınıfta döküm sevmiyorum
public interface IReplyCreator
{
IReply GetReply(ICommand command);
}
public class ReplyCreator : IReplyCreator
{
private readonly IEnumerable<ICommandHandler> _commandHandlers;
public ReplyCreator(IEnumerable<ICommandHandler> commandHandlers)
{
_commandHandlers = commandHandlers;
}
public IReply GetReply(ICommand command)
{
var commandHandler = _commandHandlers
.FirstOrDefault(x => x.CanHandle(command));
if (commandHandler == null)
return null;
return commandHandler.Handle(command);
}
}
ama bulamıyorum Bunu önlemek için herhangi bir desen. Aşağıda gösterildiği gibi genel bir arayüz oluşturabilirim, ancak ReplyCreator'da belirli bir işleyiciyi nasıl kaydedip seçebilirim? şöyle sunucusunda alınan
public interface ICommandHandler<TCommand>
where TCommand : ICommand
{
bool CanHandle(TCommand command);
IReply Handle(TCommand command);
}
komutları Json.NET ile serileştirildiğini:
JsonConvert.SerializeObject(new CommandA(), new JsonSerializerSettings
{
TypeNameHandling = TypeNameHandling.All
};)
Yani sonuçta somut komuta içine serileştirilemezse ve uygun işleyici tarafından ele alınması gereken bir dize alır. Böyle bir senaryoda oyunculardan kaçmanın bir yolu var mı? StructureMap'i IoC kitaplığım olarak kullanıyorum.
Anlaşmalı. Kolu (TCommand olarak komut) 'yerine 'Sap ((TCommand) komutu)' yazmalıdır. – Timwi
@SoftwareFactor Döküm ile kesinlikle yaşayabilirim, ancak yakın geçmişte birkaç kez benzer bir desen kullandığımı ve başka bir şeyle değiştirilebileceğini merak ettim, belki daha iyi. Ve sen harikasın, bu durumda 'olarak' kullanmamalıyım. –