具有URL路由的命令模式

时间:2016-08-02 15:50:35

标签: c# asp.net design-patterns reflection

所以我一直在寻找一个非常简单的服务命令界面,以便可以发送http cmds来控制它。

我努力的部分是实现命令的最佳方式,这些命令将基于路线。我已经在命令模式上看到了很多,这是有道理的,但有一点我试图修改。在所有情况下都有一个包含命令的字典,是否有某种方法可以摆脱字典,例如,查看类中的所有静态方法?我确定这可以通过反射来完成,但我还没有看到它的一个例子,当我找到命令模式和反射时,大多数人都说要远离它。

我的主要目标是确保如果有人添加命令他们不会忘记将其添加到字典中,我知道我希望所有静态方法都能响应路由。

这是一个好主意还是我应该说它并坚持正常模式?

我应该使用HttpListener添加一个非常基本的Web服务器 Multi-threading with .Net HttpListener

和我见过的关于我想要做的命令模式的最好的例子就是这个 using the command and factory design patterns for executing queued jobs

完整解决方案

//simple interface
interface ICommand
{
    bool Execute();
}

//example cmd
public class cmd_Restart:ICommand
{
    public bool Execute()
    {
        //put your code here
        //return true or false for success
        logger.writeLog("It was called!");
        return true;
    }
}

class commands
{
    private static Dictionary<string, Type> _commands;
    public commands()
    {
        loadCommands();
    }

    public ICommand GetCommand(string cmdName)
    {
        //should probably be more complex to make sure its found
        return (ICommand)Activator.CreateInstance(_commands[cmdName]);
    }

    private void loadCommands()
    {
        _commands = new Dictionary<string, Type>();
        var cmdType = typeof(ICommand);

        _commands = AppDomain.CurrentDomain.GetAssemblies()
            .First(a => a.GetName().Name == "DomoticzServiceManagerTest")
            .GetTypes()
            .Where(t => t.Name.StartsWith("cmd_"))
            .ToDictionary(c => c.Name.Substring(4).ToLower(),
                            c => c);
        }
}

3 个答案:

答案 0 :(得分:1)

第三次幸运!

Here是一些代码,可以找到实现特定接口的所有类型,例如ICommand接口。

Dictionary<string, Type> - 类型名称与类型中注册每种类型,比如说。

当请求进入时,获取类型。从字典中做出类似的事情;

var command = (ICommand)Activator.CreateInstance(commandType);
command.Execute();

所以现在你有一个系统可以找到类型,而无需注册它们,并自动发送。

它有点基础,但它是一种过去对我有用的模式。

答案 1 :(得分:0)

在ASP.NET MVC和WebAPI中都使用了Reflection。所以类上的方法

public class AccountController: Controller
{
    public ActionResult Login(string username, string password) 
    ...
}

Controller类和操作方法本身都是通过反射发现的,并由运行时调用。

当你谈到命令词典时,我猜你正在谈论像Nancy这样的库?

除非这是一次学习经历,否则我很想使用现有的解决方案。例如,如果ASP.NET MVC已经做了你想要的,经过实战测试,并且很容易得到帮助,那么重新发明自己的轮子可能是一个错误。

答案 2 :(得分:0)

您可能希望查看将为您执行发现部分的MEF,并且现在已内置到框架中。

你想要的是某种调度员。类似南希服务的东西,如:

发布[“/:commandName”] = _ =&gt; {}

然后选择命令名称,并发送到适当的容器。

MEF中的链接包含一个带有“ImportMany”一词的部分,该部分显示了如何根据命令名称调度命令。

作为必然结果;我已经成功使用TopShelf和Nancy来托管响应HTTP的Windows服务。