我正在实现CQRS模式。为了在我的项目中使用CQRS模式,我编写了三个命令,它们是
public class DogCommand : PetCommand
{
public DogCommand(){}
public override string Name{get; set;}
}
public class CatCommand : PetCommand
{
public CatCommand(){}
public override string Name{get; set;}
}
public abstract class PetCommand : ICommand
{
public PetCommand(){}
public virtual string Name{get; set;}
}
public interface ICommand
{
//Business logic
}
在这里,我有一个名为ICommand
的界面。 PetCommand是实现此接口的基类。派生类DogCommand
和CatCommand
继承了PetCommand
。
我还编写了基本的命令处理程序,如下所示
public abstract class BaseCommandHandler<T> : CommandHandler<T> where T : ICommand
{
protected BaseCommandHandler(string type, string name): base(type, name)
{
}
}
public abstract class CommandHandler<T> : ICommandHandler<T> where T : ICommand
{
protected CommandHandler(string type, string name)
{
//Business logic
}
protected void LogWrite(T command)
{
//Writing log
}
}
public interface ICommandHandler<in T> where T : ICommand
{
void Run(T command);
}
BaseCommandHandler
中存在的所有函数,我将在每个派生的命令处理程序中使用
现在问题出在派生类命令处理程序中
public class PetCommandHandler : BaseCommandHandler<DogCommand>, ICommandHandler<CatCommand>
{
public void Run(DogCommand dCommand)
{
this.LogWrite(dCommand)
}
public void Run(CatCommand cCommand)
{
**//Want to access this.LogWrite() with cCommand. How can I do that?**
}
}
这里我无法访问cCommand的this.LogWrite()
函数,因为PetCommandHandler
继承了 first BaseCommandHandler
和 then 实现ICommandHandle
如何访问cCommand的
this.LogWrite()
功能?
这是编译时错误:
无法从“ Command.DogCommand”转换为“ Command.CatCommand”
更新:
解决此问题的第一种方法:
我可以通过使用基本命令(即PetCommand
中的BaseCommandHandler
而不是DogCommand
来解决此问题。这将帮助我访问this.LogWrite()
函数中的所有派生类,但这将导致我实现我不想执行的空Run(PetCommand petCommand) {}
函数。
第二种方式:
每当遇到这种情况时,我都可以在LogWrite()
和virtual
中将CommandHandler
的功能更改为override
。
非常感谢有人为我提供其他解决方案。
答案 0 :(得分:0)
您有要解决的设计问题。
您正在尝试处理泛型类中的两个单独的类型。这不是可扩展的设计。
当将创建一个从PetCommand
继承的新类时,您将不得不更改PetCommand处理程序类以实现接口ICommandHandler<newPetCommand>
。这基本上是一个糟糕的设计。
您的命令处理程序类应该处理Pet,而不要处理特定类型的Pet,例如Cat或Dog。
您需要具有CommandHandler和PetCommandHandler类,如下所示。
public abstract class CommandHandler<T> : ICommandHandler<T> where T : ICommand
{
protected CommandHandler(string type, string name)
{
//Business logic
}
//Making Run method abstract so that
//individual Handler class can have their own logic in it.
public abstract void Run(T command);
//Common implementation for LogWrite.
//If this also requires override, it can be made virtual
//so that deriving class can override the logic.
protected void LogWrite(T command)
{
//Writing log
}
}
//PetCommandHandler class now can be used for any class object
//which is inheriting PetCommand class.
public class PetCommandHandler<T> : BaseCommandHandler<T> where T: PetCommand
{
public PetCommandHandler(string type, string name) : base(type, name)
{
}
public override void Run(T dCommand)
{
this.LogWrite(dCommand);
}
}
如何测试?
var dog = new DogCommand();
var commandHandler = new PetCommandHandler<DogCommand>("Dog", "Tom");
commandHandler.Run(dog);
var cat = new CatCommand();
var catHandler = new PetCommandHandler<CatCommand>("Cat", "Mini");
catHandler.Run(cat);
如果您稍后引入新的PetCommand
类,请说PandaCommand
。您仍然可以按照以下方式使用PetHandler。
var pandaHandler = new PetHandler<PandaCommand>("Panda", "Po");
var panda = new PandaCommand();
pandaHandler.Run(panda);
如果您不想为不同的PetCommand类型创建PetCommandHandler
的单独实例。您可以按以下方式更改PetCommandHandler类。
public class PetCommandHandler : BaseCommandHandler<PetCommand>
{
public PetCommandHandler(string type, string name) : base(type, name)
{
}
public override void Run(PetCommand dCommand)
{
this.LogWrite(dCommand);
}
}
使用此类,您只需要创建PetCommndHandler
的一个实例,就可以对PetCommand的任何对象执行Run
方法
var patCommandHandler = new PetCommandHandler("someType", "someName");
patCommandHandler.Run(dog);
patCommandHandler.Run(cat);
patCommandHandler.Run(panda);
我希望这可以帮助您解决问题。