[{"data":1,"prerenderedAt":387},["ShallowReactive",2],{"post-\u002Fasp-net-core-lazy-command-pattern\u002F":3},{"id":4,"title":5,"author":6,"body":7,"comments":204,"date":362,"dateModified":363,"description":364,"extension":365,"headings":366,"heroImage":372,"meta":373,"path":374,"permalink":374,"published":375,"stem":376,"tags":377,"timeToRead":386},"posts\u002Fposts\u002F2017\u002Fasp-net-core-lazy-command-pattern\u002Findex.md","ASP.NET Core Lazy Command Pattern","Muhammad Rehan Saeed",{"type":8,"value":9,"toc":201},"minimark",[10,25,28,35,59,62,65,68,84,87,98,109,112,123,145,148,156,159,170,173,184,197],[11,12,16,22],"div",{"className":13},[14,15],"custom-block","tip",[17,18,21],"p",{"className":19},[20],"custom-block-title","TLDR",[17,23,24],{},"Move your ASP.NET Core MVC action method logic into lazily loaded commands using the command pattern.",[17,26,27],{},"When writing your Controllers in ASP.NET Core, you can end up with a very long class if you're not careful. You may have written several action methods with a few lines of code in each, you may be injecting a few services into your controller and you may have commented your action methods to support Swagger. The point is it's very easy to do, here is an example:",[29,30],"pre",{"className":31,"language":32,"meta":33,"style":33,"html":34},"language-cs shiki shiki-themes light-plus monokai","cs","","\u003Cspan class=\"line\">\u003Cspan class=\"sjLUg\">[\u003C\u002Fspan>\u003Cspan class=\"sw29p\">Route\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">(\u003C\u002Fspan>\u003Cspan class=\"swiDo\">\"[controller]\"\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">)]\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sJvqV\">public\u003C\u002Fspan>\u003Cspan class=\"s4J9F\"> class\u003C\u002Fspan>\u003Cspan class=\"sw29p\"> RocketController\u003C\u002Fspan>\u003Cspan class=\"sjLUg\"> : \u003C\u002Fspan>\u003Cspan class=\"sw29p\">Controller\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sjLUg\">{\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sJvqV\">    private\u003C\u002Fspan>\u003Cspan class=\"sJvqV\"> readonly\u003C\u002Fspan>\u003Cspan class=\"sw29p\"> IPlanetRepository\u003C\u002Fspan>\u003Cspan class=\"sFrd5\"> planetRepository\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">;\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sJvqV\">    private\u003C\u002Fspan>\u003Cspan class=\"sJvqV\"> readonly\u003C\u002Fspan>\u003Cspan class=\"sw29p\"> IRocketRepository\u003C\u002Fspan>\u003Cspan class=\"sFrd5\"> rocketRepository\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">;\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan>\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sJvqV\">    public\u003C\u002Fspan>\u003Cspan class=\"sWm5y\"> RocketController\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">(\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sw29p\">        IPlanetRepository\u003C\u002Fspan>\u003Cspan class=\"sFrd5\"> planetRepository\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">,\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sw29p\">        IRocketRepository\u003C\u002Fspan>\u003Cspan class=\"sFrd5\"> rocketRepository\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">)\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sjLUg\">    {\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sK46n\">        this\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">.\u003C\u002Fspan>\u003Cspan class=\"sFrd5\">planetRepository\u003C\u002Fspan>\u003Cspan class=\"snCLD\"> =\u003C\u002Fspan>\u003Cspan class=\"sFrd5\"> planetRepository\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">;\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sK46n\">        this\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">.\u003C\u002Fspan>\u003Cspan class=\"sFrd5\">rocketRepository\u003C\u002Fspan>\u003Cspan class=\"snCLD\"> =\u003C\u002Fspan>\u003Cspan class=\"sFrd5\"> rocketRepository\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">;\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sjLUg\">    }\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sjLUg\">    \n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sjLUg\">    [\u003C\u002Fspan>\u003Cspan class=\"sw29p\">HttpGet\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">(\u003C\u002Fspan>\u003Cspan class=\"swiDo\">\"{rocketId}\"\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">)]\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sJvqV\">    public\u003C\u002Fspan>\u003Cspan class=\"sJvqV\"> async\u003C\u002Fspan>\u003Cspan class=\"sw29p\"> Task\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">&lt;\u003C\u002Fspan>\u003Cspan class=\"sw29p\">IActionResult\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">&gt; \u003C\u002Fspan>\u003Cspan class=\"sWm5y\">GetRocket\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">(\u003C\u002Fspan>\u003Cspan class=\"sJvqV\">int\u003C\u002Fspan>\u003Cspan class=\"sFrd5\"> rocketId\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">)\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sjLUg\">    {\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"s4J9F\">        var\u003C\u002Fspan>\u003Cspan class=\"sFrd5\"> rocket\u003C\u002Fspan>\u003Cspan class=\"snCLD\"> =\u003C\u002Fspan>\u003Cspan class=\"sJvqV\"> await\u003C\u002Fspan>\u003Cspan class=\"sK46n\"> this\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">.\u003C\u002Fspan>\u003Cspan class=\"sFrd5\">rocketRepository\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">.\u003C\u002Fspan>\u003Cspan class=\"sWm5y\">GetRocket\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">(\u003C\u002Fspan>\u003Cspan class=\"sFrd5\">rocketId\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">);\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"smL5M\">        if\u003C\u002Fspan>\u003Cspan class=\"sjLUg\"> (\u003C\u002Fspan>\u003Cspan class=\"sFrd5\">rocket\u003C\u002Fspan>\u003Cspan class=\"snCLD\"> ==\u003C\u002Fspan>\u003Cspan class=\"sMc8R\"> null\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">)\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sjLUg\">        {\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"smL5M\">            return\u003C\u002Fspan>\u003Cspan class=\"sK46n\"> this\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">.\u003C\u002Fspan>\u003Cspan class=\"sWm5y\">NotFound\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">();\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sjLUg\">       }\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"smL5M\">        return\u003C\u002Fspan>\u003Cspan class=\"sK46n\"> this\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">.\u003C\u002Fspan>\u003Cspan class=\"sWm5y\">Ok\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">(\u003C\u002Fspan>\u003Cspan class=\"sFrd5\">rocket\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">);\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sjLUg\">    }\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sjLUg\">    \n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sjLUg\">    [\u003C\u002Fspan>\u003Cspan class=\"sw29p\">HttpGet\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">(\u003C\u002Fspan>\u003Cspan class=\"swiDo\">\"{rocketId}\u002Flaunch\u002F{planetId}\"\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">)]\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sJvqV\">    public\u003C\u002Fspan>\u003Cspan class=\"sJvqV\"> async\u003C\u002Fspan>\u003Cspan class=\"sw29p\"> Task\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">&lt;\u003C\u002Fspan>\u003Cspan class=\"sw29p\">IActionResult\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">&gt; \u003C\u002Fspan>\u003Cspan class=\"sWm5y\">LaunchRocket\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">(\u003C\u002Fspan>\u003Cspan class=\"sJvqV\">int\u003C\u002Fspan>\u003Cspan class=\"sFrd5\"> rocketId\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">, \u003C\u002Fspan>\u003Cspan class=\"sJvqV\">int\u003C\u002Fspan>\u003Cspan class=\"sFrd5\"> planetId\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">)\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sjLUg\">    {\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"s4J9F\">        var\u003C\u002Fspan>\u003Cspan class=\"sFrd5\"> rocket\u003C\u002Fspan>\u003Cspan class=\"snCLD\"> =\u003C\u002Fspan>\u003Cspan class=\"sJvqV\"> await\u003C\u002Fspan>\u003Cspan class=\"sK46n\"> this\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">.\u003C\u002Fspan>\u003Cspan class=\"sFrd5\">rocketRepository\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">.\u003C\u002Fspan>\u003Cspan class=\"sWm5y\">GetRocket\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">(\u003C\u002Fspan>\u003Cspan class=\"sFrd5\">rocketId\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">);\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"smL5M\">        if\u003C\u002Fspan>\u003Cspan class=\"sjLUg\"> (\u003C\u002Fspan>\u003Cspan class=\"sFrd5\">rocket\u003C\u002Fspan>\u003Cspan class=\"snCLD\"> ==\u003C\u002Fspan>\u003Cspan class=\"sMc8R\"> null\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">)\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sjLUg\">        {\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"smL5M\">            return\u003C\u002Fspan>\u003Cspan class=\"sK46n\"> this\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">.\u003C\u002Fspan>\u003Cspan class=\"sWm5y\">NotFound\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">();\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sjLUg\">        }\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"s4J9F\">        var\u003C\u002Fspan>\u003Cspan class=\"sFrd5\"> planet\u003C\u002Fspan>\u003Cspan class=\"snCLD\"> =\u003C\u002Fspan>\u003Cspan class=\"sJvqV\"> await\u003C\u002Fspan>\u003Cspan class=\"sK46n\"> this\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">.\u003C\u002Fspan>\u003Cspan class=\"sFrd5\">planetRepository\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">.\u003C\u002Fspan>\u003Cspan class=\"sWm5y\">GetPlanet\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">(\u003C\u002Fspan>\u003Cspan class=\"sFrd5\">planetId\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">);\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"smL5M\">        if\u003C\u002Fspan>\u003Cspan class=\"sjLUg\"> (\u003C\u002Fspan>\u003Cspan class=\"sFrd5\">planet\u003C\u002Fspan>\u003Cspan class=\"snCLD\"> ==\u003C\u002Fspan>\u003Cspan class=\"sMc8R\"> null\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">)\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sjLUg\">        {\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"smL5M\">            return\u003C\u002Fspan>\u003Cspan class=\"sK46n\"> this\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">.\u003C\u002Fspan>\u003Cspan class=\"sWm5y\">NotFound\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">();\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sjLUg\">        }\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sK46n\">        this\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">.\u003C\u002Fspan>\u003Cspan class=\"sFrd5\">rocketRepository\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">.\u003C\u002Fspan>\u003Cspan class=\"sWm5y\">VisitPlanet\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">(\u003C\u002Fspan>\u003Cspan class=\"sFrd5\">rocket\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">, \u003C\u002Fspan>\u003Cspan class=\"sFrd5\">planet\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">);\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"smL5M\">        return\u003C\u002Fspan>\u003Cspan class=\"sK46n\"> this\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">.\u003C\u002Fspan>\u003Cspan class=\"sWm5y\">Ok\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">(\u003C\u002Fspan>\u003Cspan class=\"sFrd5\">rocket\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">);\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sjLUg\">    }\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sjLUg\">}\n\u003C\u002Fspan>\u003C\u002Fspan>",[36,37,39,58],"h1",{"id":38},"the-command-pattern",[40,41,44],"a",{"href":42,"aria-hidden":43},"#the-command-pattern","true",[45,46,52],"svg",{"xmlns":47,"xmlns:xlink":48,"viewBox":49,"version":50,"width":51,"height":51,"aria-hidden":43},"http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg","http:\u002F\u002Fwww.w3.org\u002F1999\u002Fxlink","0 0 16 16","1.1",22,[53,54],"path",{"fill":55,"fill-rule":56,"d":57},"currentColor","evenodd","M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z","The Command Pattern",[17,60,61],{},"This is where the command pattern can come in handy. The command pattern moves logic from each action method and injected dependencies into their own class like so:",[29,63],{"className":31,"language":32,"meta":33,"style":33,"html":64},"\u003Cspan class=\"line\">\u003Cspan class=\"sjLUg\">[\u003C\u002Fspan>\u003Cspan class=\"sw29p\">Route\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">(\u003C\u002Fspan>\u003Cspan class=\"swiDo\">\"[controller]\"\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">)]\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sJvqV\">public\u003C\u002Fspan>\u003Cspan class=\"s4J9F\"> class\u003C\u002Fspan>\u003Cspan class=\"sw29p\"> RocketController\u003C\u002Fspan>\u003Cspan class=\"sjLUg\"> : \u003C\u002Fspan>\u003Cspan class=\"sw29p\">Controller\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sjLUg\">{\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sJvqV\">    private\u003C\u002Fspan>\u003Cspan class=\"sJvqV\"> readonly\u003C\u002Fspan>\u003Cspan class=\"sw29p\"> Lazy\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">&lt;\u003C\u002Fspan>\u003Cspan class=\"sw29p\">IGetRocketCommand\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">&gt; \u003C\u002Fspan>\u003Cspan class=\"sFrd5\">getRocketCommand\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">;\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sJvqV\">    private\u003C\u002Fspan>\u003Cspan class=\"sJvqV\"> readonly\u003C\u002Fspan>\u003Cspan class=\"sw29p\"> Lazy\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">&lt;\u003C\u002Fspan>\u003Cspan class=\"sw29p\">ILaunchRocketCommand\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">&gt; \u003C\u002Fspan>\u003Cspan class=\"sFrd5\">launchRocketCommand\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">;\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan>\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sJvqV\">    public\u003C\u002Fspan>\u003Cspan class=\"sWm5y\"> RocketController\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">(\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sw29p\">        Lazy\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">&lt;\u003C\u002Fspan>\u003Cspan class=\"sw29p\">IGetRocketCommand\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">&gt; \u003C\u002Fspan>\u003Cspan class=\"sFrd5\">getRocketCommand\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">,\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sw29p\">        Lazy\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">&lt;\u003C\u002Fspan>\u003Cspan class=\"sw29p\">ILaunchRocketCommand\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">&gt; \u003C\u002Fspan>\u003Cspan class=\"sFrd5\">launchRocketCommand\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">)\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sjLUg\">    {\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sK46n\">        this\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">.\u003C\u002Fspan>\u003Cspan class=\"sFrd5\">getRocketCommand\u003C\u002Fspan>\u003Cspan class=\"snCLD\"> =\u003C\u002Fspan>\u003Cspan class=\"sFrd5\"> getRocketCommand\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">;\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sK46n\">        this\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">.\u003C\u002Fspan>\u003Cspan class=\"sFrd5\">launchRocketCommand\u003C\u002Fspan>\u003Cspan class=\"snCLD\"> =\u003C\u002Fspan>\u003Cspan class=\"sFrd5\"> launchRocketCommand\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">;\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sjLUg\">    }\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan>\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sjLUg\">    [\u003C\u002Fspan>\u003Cspan class=\"sw29p\">HttpGet\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">(\u003C\u002Fspan>\u003Cspan class=\"swiDo\">\"{rocketId}\"\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">)]\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sJvqV\">    public\u003C\u002Fspan>\u003Cspan class=\"sw29p\"> Task\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">&lt;\u003C\u002Fspan>\u003Cspan class=\"sw29p\">IActionResult\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">&gt; \u003C\u002Fspan>\u003Cspan class=\"sWm5y\">GetRocket\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">(\u003C\u002Fspan>\u003Cspan class=\"sJvqV\">int\u003C\u002Fspan>\u003Cspan class=\"sFrd5\"> rocketId\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">) \u003C\u002Fspan>\u003Cspan class=\"snCLD\">=&gt;\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sK46n\">        this\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">.\u003C\u002Fspan>\u003Cspan class=\"sFrd5\">getRocketCommand\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">.\u003C\u002Fspan>\u003Cspan class=\"sFrd5\">Value\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">.\u003C\u002Fspan>\u003Cspan class=\"sWm5y\">ExecuteAsync\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">(\u003C\u002Fspan>\u003Cspan class=\"sFrd5\">rocketId\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">);\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan>\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sjLUg\">    [\u003C\u002Fspan>\u003Cspan class=\"sw29p\">HttpGet\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">(\u003C\u002Fspan>\u003Cspan class=\"swiDo\">\"{rocketId}\u002Flaunch\u002F{planetId}\"\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">)]\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sJvqV\">    public\u003C\u002Fspan>\u003Cspan class=\"sw29p\"> Task\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">&lt;\u003C\u002Fspan>\u003Cspan class=\"sw29p\">IActionResult\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">&gt; \u003C\u002Fspan>\u003Cspan class=\"sWm5y\">LaunchRocket\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">(\u003C\u002Fspan>\u003Cspan class=\"sJvqV\">int\u003C\u002Fspan>\u003Cspan class=\"sFrd5\"> rocketId\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">, \u003C\u002Fspan>\u003Cspan class=\"sJvqV\">int\u003C\u002Fspan>\u003Cspan class=\"sFrd5\"> planetId\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">) \u003C\u002Fspan>\u003Cspan class=\"snCLD\">=&gt;\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sK46n\">        this\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">.\u003C\u002Fspan>\u003Cspan class=\"sFrd5\">launchRocketCommand\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">.\u003C\u002Fspan>\u003Cspan class=\"sFrd5\">Value\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">.\u003C\u002Fspan>\u003Cspan class=\"sWm5y\">ExecuteAsync\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">(\u003C\u002Fspan>\u003Cspan class=\"sFrd5\">rocketId\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">, \u003C\u002Fspan>\u003Cspan class=\"sFrd5\">planetId\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">);\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sjLUg\">}\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan>\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sJvqV\">public\u003C\u002Fspan>\u003Cspan class=\"s4J9F\"> interface\u003C\u002Fspan>\u003Cspan class=\"sw29p\"> IGetRocketCommand\u003C\u002Fspan>\u003Cspan class=\"sjLUg\"> : \u003C\u002Fspan>\u003Cspan class=\"sw29p\">IAsyncCommand\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">&lt;\u003C\u002Fspan>\u003Cspan class=\"sJvqV\">int\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">&gt;\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sjLUg\">{\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sjLUg\">}\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan>\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sJvqV\">public\u003C\u002Fspan>\u003Cspan class=\"s4J9F\"> class\u003C\u002Fspan>\u003Cspan class=\"sw29p\"> GetRocketCommand\u003C\u002Fspan>\u003Cspan class=\"sjLUg\"> : \u003C\u002Fspan>\u003Cspan class=\"sw29p\">IGetRocketCommand\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sjLUg\">{\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sJvqV\">    private\u003C\u002Fspan>\u003Cspan class=\"sJvqV\"> readonly\u003C\u002Fspan>\u003Cspan class=\"sw29p\"> IRocketRepository\u003C\u002Fspan>\u003Cspan class=\"sFrd5\"> rocketRepository\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">;\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan>\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sJvqV\">    public\u003C\u002Fspan>\u003Cspan class=\"sWm5y\"> GetRocketCommand\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">(\u003C\u002Fspan>\u003Cspan class=\"sw29p\">IRocketRepository\u003C\u002Fspan>\u003Cspan class=\"sFrd5\"> rocketRepository\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">) \u003C\u002Fspan>\u003Cspan class=\"snCLD\">=&gt;\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sK46n\">        this\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">.\u003C\u002Fspan>\u003Cspan class=\"sFrd5\">rocketRepository\u003C\u002Fspan>\u003Cspan class=\"snCLD\"> =\u003C\u002Fspan>\u003Cspan class=\"sFrd5\"> rocketRepository\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">;\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan>\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sJvqV\">    public\u003C\u002Fspan>\u003Cspan class=\"sJvqV\"> async\u003C\u002Fspan>\u003Cspan class=\"sw29p\"> Task\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">&lt;\u003C\u002Fspan>\u003Cspan class=\"sw29p\">IActionResult\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">&gt; \u003C\u002Fspan>\u003Cspan class=\"sWm5y\">ExecuteAsync\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">(\u003C\u002Fspan>\u003Cspan class=\"sJvqV\">int\u003C\u002Fspan>\u003Cspan class=\"sFrd5\"> rocketId\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">)\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sjLUg\">    {\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"s4J9F\">        var\u003C\u002Fspan>\u003Cspan class=\"sFrd5\"> rocket\u003C\u002Fspan>\u003Cspan class=\"snCLD\"> =\u003C\u002Fspan>\u003Cspan class=\"sJvqV\"> await\u003C\u002Fspan>\u003Cspan class=\"sK46n\"> this\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">.\u003C\u002Fspan>\u003Cspan class=\"sFrd5\">rocketRepository\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">.\u003C\u002Fspan>\u003Cspan class=\"sWm5y\">GetRocket\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">(\u003C\u002Fspan>\u003Cspan class=\"sFrd5\">rocketId\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">);\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"smL5M\">        if\u003C\u002Fspan>\u003Cspan class=\"sjLUg\"> (\u003C\u002Fspan>\u003Cspan class=\"sFrd5\">rocket\u003C\u002Fspan>\u003Cspan class=\"snCLD\"> ==\u003C\u002Fspan>\u003Cspan class=\"sMc8R\"> null\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">)\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sjLUg\">        {\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"smL5M\">            return\u003C\u002Fspan>\u003Cspan class=\"sJvqV\"> new\u003C\u002Fspan>\u003Cspan class=\"sw29p\"> NotFoundResult\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">();\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sjLUg\">        }\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"smL5M\">        return\u003C\u002Fspan>\u003Cspan class=\"sJvqV\"> new\u003C\u002Fspan>\u003Cspan class=\"sw29p\"> OkObjectResult\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">(\u003C\u002Fspan>\u003Cspan class=\"sFrd5\">rocket\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">);\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sjLUg\">    }\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sjLUg\">}\n\u003C\u002Fspan>\u003C\u002Fspan>",[17,66,67],{},"All the logic and dependencies in the controllers gets moved to the command which now has a single responsibility. The controller now has a different set of dependencies, it now lazily injects one command per action method.",[17,69,70,71,75,76,79,80,83],{},"You may have noticed the ",[72,73,74],"code",{},"IAsyncCommand"," interface. I keep four of these handy to inherit from. They all outline an ",[72,77,78],{},"ExecuteAsync"," method to execute the command and return an ",[72,81,82],{},"IActionResult"," but they have a differing number of parameters. I personally feel if you are needing more than three parameters you should be using a class to represent your parameters, so I've put the limit on three parameters.",[29,85],{"className":31,"language":32,"meta":33,"style":33,"html":86},"\u003Cspan class=\"line\">\u003Cspan class=\"sJvqV\">public\u003C\u002Fspan>\u003Cspan class=\"s4J9F\"> interface\u003C\u002Fspan>\u003Cspan class=\"sw29p\"> IAsyncCommand\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sjLUg\">{\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sw29p\">    Task\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">&lt;\u003C\u002Fspan>\u003Cspan class=\"sw29p\">IActionResult\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">&gt; \u003C\u002Fspan>\u003Cspan class=\"sWm5y\">ExecuteAsync\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">();\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sjLUg\">}\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sJvqV\">public\u003C\u002Fspan>\u003Cspan class=\"s4J9F\"> interface\u003C\u002Fspan>\u003Cspan class=\"sw29p\"> IAsyncCommand\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">&lt;\u003C\u002Fspan>\u003Cspan class=\"sw29p\">T\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">&gt;\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sjLUg\">{\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sw29p\">    Task\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">&lt;\u003C\u002Fspan>\u003Cspan class=\"sw29p\">IActionResult\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">&gt; \u003C\u002Fspan>\u003Cspan class=\"sWm5y\">ExecuteAsync\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">(\u003C\u002Fspan>\u003Cspan class=\"sw29p\">T\u003C\u002Fspan>\u003Cspan class=\"sFrd5\"> parameter\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">);\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sjLUg\">}\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sJvqV\">public\u003C\u002Fspan>\u003Cspan class=\"s4J9F\"> interface\u003C\u002Fspan>\u003Cspan class=\"sw29p\"> IAsyncCommand\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">&lt;\u003C\u002Fspan>\u003Cspan class=\"sw29p\">T1\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">, \u003C\u002Fspan>\u003Cspan class=\"sw29p\">T2\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">&gt;\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sjLUg\">{\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sw29p\">    Task\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">&lt;\u003C\u002Fspan>\u003Cspan class=\"sw29p\">IActionResult\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">&gt; \u003C\u002Fspan>\u003Cspan class=\"sWm5y\">ExecuteAsync\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">(\u003C\u002Fspan>\u003Cspan class=\"sw29p\">T1\u003C\u002Fspan>\u003Cspan class=\"sFrd5\"> parameter1\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">, \u003C\u002Fspan>\u003Cspan class=\"sw29p\">T2\u003C\u002Fspan>\u003Cspan class=\"sFrd5\"> parameter2\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">);\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sjLUg\">}\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sJvqV\">public\u003C\u002Fspan>\u003Cspan class=\"s4J9F\"> interface\u003C\u002Fspan>\u003Cspan class=\"sw29p\"> IAsyncCommand\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">&lt;\u003C\u002Fspan>\u003Cspan class=\"sw29p\">T1\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">, \u003C\u002Fspan>\u003Cspan class=\"sw29p\">T2\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">, \u003C\u002Fspan>\u003Cspan class=\"sw29p\">T3\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">&gt;\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sjLUg\">{\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sw29p\">    Task\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">&lt;\u003C\u002Fspan>\u003Cspan class=\"sw29p\">IActionResult\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">&gt; \u003C\u002Fspan>\u003Cspan class=\"sWm5y\">ExecuteAsync\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">(\u003C\u002Fspan>\u003Cspan class=\"sw29p\">T1\u003C\u002Fspan>\u003Cspan class=\"sFrd5\"> parameter1\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">, \u003C\u002Fspan>\u003Cspan class=\"sw29p\">T2\u003C\u002Fspan>\u003Cspan class=\"sFrd5\"> parameter2\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">, \u003C\u002Fspan>\u003Cspan class=\"sw29p\">T3\u003C\u002Fspan>\u003Cspan class=\"sFrd5\"> parameter3\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">);\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sjLUg\">}\n\u003C\u002Fspan>\u003C\u002Fspan>",[36,88,90,97],{"id":89},"why-so-lazy",[40,91,93],{"href":92,"aria-hidden":43},"#why-so-lazy",[45,94,95],{"xmlns":47,"xmlns:xlink":48,"viewBox":49,"version":50,"width":51,"height":51,"aria-hidden":43},[53,96],{"fill":55,"fill-rule":56,"d":57},"Why so Lazy?",[17,99,100,101,104,105,108],{},"Why do we use ",[72,102,103],{},"Lazy\u003CT>","? Well the answer is that if we have multiple action methods on our controller, we don't want to instantiate the dependencies for every action method if we are only planning on using one action method. Registering our Lazy commands requires a bit of extra work in out ",[72,106,107],{},"Startup.cs",". We can register lazy dependencies like so:",[29,110],{"className":31,"language":32,"meta":33,"style":33,"html":111},"\u003Cspan class=\"line\">\u003Cspan class=\"sJvqV\">public\u003C\u002Fspan>\u003Cspan class=\"sJvqV\"> void\u003C\u002Fspan>\u003Cspan class=\"sWm5y\"> ConfigureServices\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">(\u003C\u002Fspan>\u003Cspan class=\"sw29p\">IServiceCollection\u003C\u002Fspan>\u003Cspan class=\"sFrd5\"> services\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">)\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sjLUg\">{\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"s1q82\">    \u002F\u002F ...Omitted\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sFrd5\">    services\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sjLUg\">        .\u003C\u002Fspan>\u003Cspan class=\"sWm5y\">AddScoped\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">&lt;\u003C\u002Fspan>\u003Cspan class=\"sw29p\">IGetRocketCommand\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">, \u003C\u002Fspan>\u003Cspan class=\"sw29p\">GetRocketCommand\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">&gt;()\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sjLUg\">        .\u003C\u002Fspan>\u003Cspan class=\"sWm5y\">AddScoped\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">(\u003C\u002Fspan>\u003Cspan class=\"sFrd5\">x\u003C\u002Fspan>\u003Cspan class=\"snCLD\"> =&gt;\u003C\u002Fspan>\u003Cspan class=\"sJvqV\"> new\u003C\u002Fspan>\u003Cspan class=\"sw29p\"> Lazy\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">&lt;\u003C\u002Fspan>\u003Cspan class=\"sw29p\">IGetRocketCommand\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">&gt;(\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sjLUg\">            () \u003C\u002Fspan>\u003Cspan class=\"snCLD\">=&gt;\u003C\u002Fspan>\u003Cspan class=\"sFrd5\"> x\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">.\u003C\u002Fspan>\u003Cspan class=\"sWm5y\">GetRequiredService\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">&lt;\u003C\u002Fspan>\u003Cspan class=\"sw29p\">IGetRocketCommand\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">&gt;()));\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sjLUg\">}\n\u003C\u002Fspan>\u003C\u002Fspan>",[36,113,115,122],{"id":114},"httpcontext-and-actioncontext",[40,116,118],{"href":117,"aria-hidden":43},"#httpcontext-and-actioncontext",[45,119,120],{"xmlns":47,"xmlns:xlink":48,"viewBox":49,"version":50,"width":51,"height":51,"aria-hidden":43},[53,121],{"fill":55,"fill-rule":56,"d":57},"HttpContext and ActionContext",[17,124,125,126,129,130,133,134,129,137,140,141,144],{},"Now you might be thinking, how do I access the ",[72,127,128],{},"HttpContext"," or ",[72,131,132],{},"ActionContext"," if I want to set a HTTP header for example? Well, you can use the ",[72,135,136],{},"IHttpContextAccessor",[72,138,139],{},"IActionContextAccessor"," interfaces for this purpose. You can register them in your ",[72,142,143],{},"Startup"," class like so:",[29,146],{"className":31,"language":32,"meta":33,"style":33,"html":147},"\u003Cspan class=\"line\">\u003Cspan class=\"sJvqV\">public\u003C\u002Fspan>\u003Cspan class=\"sJvqV\"> void\u003C\u002Fspan>\u003Cspan class=\"sWm5y\"> ConfigureServices\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">(\u003C\u002Fspan>\u003Cspan class=\"sw29p\">IServiceCollection\u003C\u002Fspan>\u003Cspan class=\"sFrd5\"> services\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">)\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sjLUg\">{\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"s1q82\">    \u002F\u002F ...Omitted\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sFrd5\">    services\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sjLUg\">        .\u003C\u002Fspan>\u003Cspan class=\"sWm5y\">AddSingleton\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">&lt;\u003C\u002Fspan>\u003Cspan class=\"sw29p\">IHttpContextAccessor\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">, \u003C\u002Fspan>\u003Cspan class=\"sw29p\">HttpContextAccessor\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">&gt;()\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sjLUg\">        .\u003C\u002Fspan>\u003Cspan class=\"sWm5y\">AddSingleton\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">&lt;\u003C\u002Fspan>\u003Cspan class=\"sw29p\">IActionContextAccessor\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">, \u003C\u002Fspan>\u003Cspan class=\"sw29p\">ActionContextAccessor\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">&gt;();\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sjLUg\">}\n\u003C\u002Fspan>\u003C\u002Fspan>",[17,149,150,151,129,153,155],{},"Notice that they can be registered as singletons. You can then use them to get hold of the ",[72,152,128],{},[72,154,132],{}," objects for the current HTTP request. Here is a really simple example.",[29,157],{"className":31,"language":32,"meta":33,"style":33,"html":158},"\u003Cspan class=\"line\">\u003Cspan class=\"sJvqV\">public\u003C\u002Fspan>\u003Cspan class=\"s4J9F\"> class\u003C\u002Fspan>\u003Cspan class=\"sw29p\"> SetHttpHeaderCommand\u003C\u002Fspan>\u003Cspan class=\"sjLUg\"> : \u003C\u002Fspan>\u003Cspan class=\"sw29p\">ISetHttpHeaderCommand\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sjLUg\">{\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sJvqV\">    private\u003C\u002Fspan>\u003Cspan class=\"sJvqV\"> readonly\u003C\u002Fspan>\u003Cspan class=\"sw29p\"> IHttpContextAccessor\u003C\u002Fspan>\u003Cspan class=\"sFrd5\"> httpContextAccessor\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">;\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan>\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sJvqV\">    public\u003C\u002Fspan>\u003Cspan class=\"sWm5y\"> GetRocketCommand\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">(\u003C\u002Fspan>\u003Cspan class=\"sw29p\">IHttpContextAccessor\u003C\u002Fspan>\u003Cspan class=\"sFrd5\"> httpContextAccessor\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">) \u003C\u002Fspan>\u003Cspan class=\"snCLD\">=&gt;\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sK46n\">        this\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">.\u003C\u002Fspan>\u003Cspan class=\"sFrd5\">httpContextAccessor\u003C\u002Fspan>\u003Cspan class=\"snCLD\"> =\u003C\u002Fspan>\u003Cspan class=\"sFrd5\"> httpContextAccessor\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">;\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan>\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sJvqV\">    public\u003C\u002Fspan>\u003Cspan class=\"sJvqV\"> async\u003C\u002Fspan>\u003Cspan class=\"sw29p\"> Task\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">&lt;\u003C\u002Fspan>\u003Cspan class=\"sw29p\">IActionResult\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">&gt; \u003C\u002Fspan>\u003Cspan class=\"sWm5y\">ExecuteAsync\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">()\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sjLUg\">    {\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sK46n\">        this\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">.\u003C\u002Fspan>\u003Cspan class=\"sFrd5\">httpContextAccessor\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">.\u003C\u002Fspan>\u003Cspan class=\"sFrd5\">HttpContext\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">.\u003C\u002Fspan>\u003Cspan class=\"sFrd5\">Response\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">.\u003C\u002Fspan>\u003Cspan class=\"sFrd5\">Headers\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">.\u003C\u002Fspan>\u003Cspan class=\"sWm5y\">Add\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">(\u003C\u002Fspan>\u003Cspan class=\"swiDo\">\"X-Rocket\"\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">, \u003C\u002Fspan>\u003Cspan class=\"swiDo\">\"Saturn V\"\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">);\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"smL5M\">        return\u003C\u002Fspan>\u003Cspan class=\"sJvqV\"> new\u003C\u002Fspan>\u003Cspan class=\"sw29p\"> OkResult\u003C\u002Fspan>\u003Cspan class=\"sjLUg\">();\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sjLUg\">    }\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan class=\"sjLUg\">}\n\u003C\u002Fspan>\u003C\u002Fspan>",[36,160,162,169],{"id":161},"unit-testing",[40,163,165],{"href":164,"aria-hidden":43},"#unit-testing",[45,166,167],{"xmlns":47,"xmlns:xlink":48,"viewBox":49,"version":50,"width":51,"height":51,"aria-hidden":43},[53,168],{"fill":55,"fill-rule":56,"d":57},"Unit Testing",[17,171,172],{},"Another upside to the command pattern is that testing each command becomes super simple. You don't need to setup a controller with lots of dependencies that you don't care about. You only need to write test code for that single feature.",[36,174,176,183],{"id":175},"conclusions",[40,177,179],{"href":178,"aria-hidden":43},"#conclusions",[45,180,181],{"xmlns":47,"xmlns:xlink":48,"viewBox":49,"version":50,"width":51,"height":51,"aria-hidden":43},[53,182],{"fill":55,"fill-rule":56,"d":57},"Conclusions",[17,185,186,187,196],{},"For a full working example, take a look at the ",[40,188,195],{"href":189,"rel":190,"target":194},"https:\u002F\u002Fgithub.com\u002FDotnet-Boxed\u002FTemplates\u002Fblob\u002Fmain\u002FDocs\u002FAPI.md",[191,192,193],"nofollow","noopener","noreferrer","_blank",".NET Boxed API"," project template which makes full use of the Lazy Command Pattern.",[198,199,200],"style",{},"html pre.shiki code .sjLUg, html code.shiki .sjLUg{--shiki-default:#000000;--shiki-dark:#F8F8F2}html pre.shiki code .sw29p, html code.shiki .sw29p{--shiki-default:#267F99;--shiki-default-text-decoration:inherit;--shiki-dark:#A6E22E;--shiki-dark-text-decoration:underline}html pre.shiki code .swiDo, html code.shiki .swiDo{--shiki-default:#A31515;--shiki-dark:#E6DB74}html pre.shiki code .sJvqV, html code.shiki .sJvqV{--shiki-default:#0000FF;--shiki-dark:#F92672}html pre.shiki code .s4J9F, html code.shiki .s4J9F{--shiki-default:#0000FF;--shiki-default-font-style:inherit;--shiki-dark:#66D9EF;--shiki-dark-font-style:italic}html pre.shiki code .sFrd5, html code.shiki .sFrd5{--shiki-default:#001080;--shiki-dark:#F8F8F2}html pre.shiki code .sWm5y, html code.shiki .sWm5y{--shiki-default:#795E26;--shiki-dark:#A6E22E}html pre.shiki code .sK46n, html code.shiki .sK46n{--shiki-default:#0000FF;--shiki-dark:#FD971F}html pre.shiki code .snCLD, html code.shiki .snCLD{--shiki-default:#000000;--shiki-dark:#F92672}html pre.shiki code .smL5M, html code.shiki .smL5M{--shiki-default:#AF00DB;--shiki-dark:#F92672}html pre.shiki code .sMc8R, html code.shiki .sMc8R{--shiki-default:#0000FF;--shiki-dark:#AE81FF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .s1q82, html code.shiki .s1q82{--shiki-default:#008000;--shiki-dark:#88846F}",{"title":33,"searchDepth":202,"depth":202,"links":203},2,[],{"issue":205,"comments":209},{"number":206,"title":207,"html_url":208},57,"[Comment] ASP.NET Core Lazy Command Pattern","https:\u002F\u002Fgithub.com\u002FRehanSaeed\u002Frehansaeed.github.io\u002Fissues\u002F57",[210,222,230,238,246,254,262,270,278,286,294,302,310,318,326,334,342,353],{"id":211,"html_url":212,"body_html":213,"created_at":214,"user":215,"reactions":219},627236318,"https:\u002F\u002Fgithub.com\u002FRehanSaeed\u002Frehansaeed.github.io\u002Fissues\u002F57#issuecomment-627236318","\n\u003Cp>\u003Ca target=\"_blank\" rel=\"nofollow noopener noreferrer\" href=\"https:\u002F\u002Fcamo.githubusercontent.com\u002F073a637e433812126b5ee5a88d9b27ce08c510387a14507f2429287cfae86b16\u002F68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f63386561643331323263363239313934636233306437623331636461363962653f733d393626643d6d6d26723d67\">\u003Cimg alt=\"Mike-EEE\" height=\"40\" width=\"40\" src=\"https:\u002F\u002Fcamo.githubusercontent.com\u002F073a637e433812126b5ee5a88d9b27ce08c510387a14507f2429287cfae86b16\u002F68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f63386561643331323263363239313934636233306437623331636461363962653f733d393626643d6d6d26723d67\" \u002F>\u003C\u002Fa> \u003Cstrong>\u003Ca rel=\"nofollow noopener noreferrer\" target=\"_blank\" href=\"http:\u002F\u002Fblog.developers.win\u002F\">Mike-EEE\u003C\u002Fa>\u003C\u002Fstrong> commented on \u003Cstrong>2017-04-08 12:45:46\u003C\u002Fstrong>\u003C\u002Fp>\n\u003Cp>Command pattern is indeed awesome!  Thank you for promoting it.  As you may know, it was a staple in WPF development.\u003C\u002Fp>\n\u003Cp>Quick commentary, however. ;)  What used to be a simple:\u003C\u002Fp>\n\u003Cdiv>\u003Cpre>\u003Cspan>void\u003C\u002Fspan> \u003Cspan>ICommand\u003C\u002Fspan>\u003Cspan>.\u003C\u002Fspan>Execute\u003Cspan>(\u003C\u002Fspan>\u003Cspan>T\u003C\u002Fspan> \u003Cspan>parameter\u003C\u002Fspan>\u003Cspan>)\u003C\u002Fspan>\u003Cspan>\u003C\u002Fspan> \u003C\u002Fpre>\u003C\u002Fdiv>\n\u003Cp>... in WPF is now:\u003C\u002Fp>\n\u003Cdiv>\u003Cpre>\u003Cspan>Task\u003C\u002Fspan> \u003Cspan>IAsyncCommand\u003C\u002Fspan>\u003Cspan>.\u003C\u002Fspan>ExecuteAsync\u003Cspan>(\u003C\u002Fspan>\u003Cspan>T\u003C\u002Fspan> \u003Cspan>parameter\u003C\u002Fspan>\u003Cspan>)\u003C\u002Fspan>\u003Cspan>\u003C\u002Fspan>\u003C\u002Fpre>\u003C\u002Fdiv>\n\u003Cp>... in .NET Core.  So, 38 characters \"old\" way vs. 62 characters \"new\" way. So much for progress. ;)  As you are using an expression body for the constructor I am sure you can appreciate the sentiment that less code is better.\u003C\u002Fp>\n\u003Cp>\u003Ca rel=\"nofollow noopener noreferrer\" target=\"_blank\" href=\"https:\u002F\u002Fvisualstudio.uservoice.com\u002Fforums\u002F121579-visual-studio-ide\u002Fsuggestions\u002F9126493-improve-asynchronous-programming-model\">https:\u002F\u002Fvisualstudio.uservoice.com\u002Fforums\u002F121579-visual-studio-ide\u002Fsuggestions\u002F9126493-improve-asynchronous-programming-model\u003C\u002Fa>\u003C\u002Fp>\n\u003Cp>Additionally, this design muddies the water with command and query separation, essentially forcing you to enable every \"query\" method (anything that returns a result) into a command method, which implicitly changes state and has side effects (which query methods are not supposed to have).\u003C\u002Fp>\n\u003Cp>Food for thought. :)\u003C\u002Fp>","2020-05-12T09:51:20Z",{"login":216,"avatar_url":217,"html_url":218},"RehanSaeed","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F2270364?v=4","https:\u002F\u002Fgithub.com\u002FRehanSaeed",{"url":220,"total_count":221,"+1":221,"-1":221,"laugh":221,"hooray":221,"confused":221,"heart":221,"rocket":221,"eyes":221},"https:\u002F\u002Fapi.github.com\u002Frepos\u002FRehanSaeed\u002Frehansaeed.github.io\u002Fissues\u002Fcomments\u002F627236318\u002Freactions",0,{"id":223,"html_url":224,"body_html":225,"created_at":226,"user":227,"reactions":228},627236379,"https:\u002F\u002Fgithub.com\u002FRehanSaeed\u002Frehansaeed.github.io\u002Fissues\u002F57#issuecomment-627236379","\n\u003Cp>\u003Ca target=\"_blank\" rel=\"nofollow noopener noreferrer\" href=\"https:\u002F\u002Fcamo.githubusercontent.com\u002F073a637e433812126b5ee5a88d9b27ce08c510387a14507f2429287cfae86b16\u002F68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f63386561643331323263363239313934636233306437623331636461363962653f733d393626643d6d6d26723d67\">\u003Cimg alt=\"Mike-EEE\" height=\"40\" width=\"40\" src=\"https:\u002F\u002Fcamo.githubusercontent.com\u002F073a637e433812126b5ee5a88d9b27ce08c510387a14507f2429287cfae86b16\u002F68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f63386561643331323263363239313934636233306437623331636461363962653f733d393626643d6d6d26723d67\" \u002F>\u003C\u002Fa> \u003Cstrong>\u003Ca rel=\"nofollow noopener noreferrer\" target=\"_blank\" href=\"http:\u002F\u002Fblog.developers.win\u002F\">Mike-EEE\u003C\u002Fa>\u003C\u002Fstrong> commented on \u003Cstrong>2017-04-08 12:49:17\u003C\u002Fstrong>\u003C\u002Fp>\n\u003Cblockquote>\n\u003Cp>Command pattern is indeed awesome!  Thank you for promoting it.  As you may know, it was a staple in WPF development.\u003C\u002Fp>\n\u003Cp>Quick commentary, however. ;)  What used to be a simple:\u003C\u002Fp>\n\u003Cdiv>\u003Cpre>\u003Cspan>void\u003C\u002Fspan> \u003Cspan>ICommand\u003C\u002Fspan>\u003Cspan>.\u003C\u002Fspan>Execute\u003Cspan>(\u003C\u002Fspan>\u003Cspan>T\u003C\u002Fspan> \u003Cspan>parameter\u003C\u002Fspan>\u003Cspan>)\u003C\u002Fspan>\u003Cspan>\u003C\u002Fspan> \u003C\u002Fpre>\u003C\u002Fdiv>\n\u003Cp>... in WPF is now:\u003C\u002Fp>\n\u003Cdiv>\u003Cpre>\u003Cspan>Task\u003C\u002Fspan> \u003Cspan>IAsyncCommand\u003C\u002Fspan>\u003Cspan>.\u003C\u002Fspan>ExecuteAsync\u003Cspan>(\u003C\u002Fspan>\u003Cspan>T\u003C\u002Fspan> \u003Cspan>parameter\u003C\u002Fspan>\u003Cspan>)\u003C\u002Fspan>\u003Cspan>\u003C\u002Fspan>\u003C\u002Fpre>\u003C\u002Fdiv>\n\u003Cp>... in .NET Core.  So, 38 characters \"old\" way vs. 62 characters \"new\" way. So much for progress. ;)  As you are using an expression body for the constructor I am sure you can appreciate the sentiment that less code is better.\u003C\u002Fp>\n\u003Cp>\u003Ca rel=\"nofollow noopener noreferrer\" target=\"_blank\" href=\"https:\u002F\u002Fvisualstudio.uservoice.com\u002Fforums\u002F121579-visual-studio-ide\u002Fsuggestions\u002F9126493-improve-asynchronous-programming-model\">https:\u002F\u002Fvisualstudio.uservoice.com\u002Fforums\u002F121579-visual-studio-ide\u002Fsuggestions\u002F9126493-improve-asynchronous-programming-model\u003C\u002Fa>\u003C\u002Fp>\n\u003Cp>Additionally, this design muddies the water with command and query separation, essentially forcing you to enable every \"query\" method (anything that returns a result) into a command method, which implicitly changes state and has side effects (which query methods are not supposed to have).\u003C\u002Fp>\n\u003Cp>Food for thought. :)\u003C\u002Fp>\n\u003C\u002Fblockquote>\n\u003Cp>Boo, the blog formatted out the brackets.  Let's see if JSON-based formatting works (sigh):\u003C\u002Fp>\n\u003Cdiv>\u003Cpre>\u003Cspan>void\u003C\u002Fspan> \u003Cspan>ICommand\u003C\u002Fspan>\u003Cspan>\u003C\u002Fspan>\u003Cspan>{\u003C\u002Fspan>\u003Cspan>T\u003C\u002Fspan>\u003Cspan>}\u003C\u002Fspan>\u003Cspan>.\u003C\u002Fspan>\u003Cspan>Execute\u003C\u002Fspan>\u003Cspan>(\u003C\u002Fspan>\u003Cspan>T\u003C\u002Fspan> \u003Cspan>parameter\u003C\u002Fspan>\u003Cspan>)\u003C\u002Fspan>\n\nTask\u003Cspan>{\u003C\u002Fspan>IActionResult\u003Cspan>}\u003C\u002Fspan> IAsyncCommand\u003Cspan>{\u003C\u002Fspan>T\u003Cspan>}\u003C\u002Fspan>\u003Cspan>.\u003C\u002Fspan>\u003Cspan>ExecuteAsync\u003C\u002Fspan>\u003Cspan>(\u003C\u002Fspan>\u003Cspan>T\u003C\u002Fspan> \u003Cspan>parameter\u003C\u002Fspan>\u003Cspan>)\u003C\u002Fspan>\u003Cspan>\u003C\u002Fspan>\u003C\u002Fpre>\u003C\u002Fdiv>\n\u003Cp>It's actually 37 \"old\" vs 62 \"new.\"\u003C\u002Fp>","2020-05-12T09:51:27Z",{"login":216,"avatar_url":217,"html_url":218},{"url":229,"total_count":221,"+1":221,"-1":221,"laugh":221,"hooray":221,"confused":221,"heart":221,"rocket":221,"eyes":221},"https:\u002F\u002Fapi.github.com\u002Frepos\u002FRehanSaeed\u002Frehansaeed.github.io\u002Fissues\u002Fcomments\u002F627236379\u002Freactions",{"id":231,"html_url":232,"body_html":233,"created_at":234,"user":235,"reactions":236},627236448,"https:\u002F\u002Fgithub.com\u002FRehanSaeed\u002Frehansaeed.github.io\u002Fissues\u002F57#issuecomment-627236448","\n\u003Cp>\u003Ca target=\"_blank\" rel=\"nofollow noopener noreferrer\" href=\"https:\u002F\u002Fcamo.githubusercontent.com\u002F6be4cff7e60019bb481bce35c8ed7283a99c0acce5921f7326b1760cd5c502f0\u002F68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f31383366663661333737333663333132366362363130633262386661653966353f733d393626643d6d6d26723d67\">\u003Cimg alt=\"Manuel Grundner\" height=\"40\" width=\"40\" src=\"https:\u002F\u002Fcamo.githubusercontent.com\u002F6be4cff7e60019bb481bce35c8ed7283a99c0acce5921f7326b1760cd5c502f0\u002F68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f31383366663661333737333663333132366362363130633262386661653966353f733d393626643d6d6d26723d67\" \u002F>\u003C\u002Fa> \u003Cstrong>\u003Ca rel=\"nofollow noopener noreferrer\" target=\"_blank\" href=\"http:\u002F\u002Fblog.delegate.at\u002F\">Manuel Grundner\u003C\u002Fa>\u003C\u002Fstrong> commented on \u003Cstrong>2017-04-08 14:20:58\u003C\u002Fstrong>\u003C\u002Fp>\n\u003Cp>I totally understand the SRP and the IOC Concept behind this, but whats then the purpose of the Controller? Besides declaring The Routes? I mean in a more reallife Example?\u003C\u002Fp>","2020-05-12T09:51:35Z",{"login":216,"avatar_url":217,"html_url":218},{"url":237,"total_count":221,"+1":221,"-1":221,"laugh":221,"hooray":221,"confused":221,"heart":221,"rocket":221,"eyes":221},"https:\u002F\u002Fapi.github.com\u002Frepos\u002FRehanSaeed\u002Frehansaeed.github.io\u002Fissues\u002Fcomments\u002F627236448\u002Freactions",{"id":239,"html_url":240,"body_html":241,"created_at":242,"user":243,"reactions":244},627236510,"https:\u002F\u002Fgithub.com\u002FRehanSaeed\u002Frehansaeed.github.io\u002Fissues\u002F57#issuecomment-627236510","\n\u003Cp>\u003Ca target=\"_blank\" rel=\"nofollow noopener noreferrer\" href=\"https:\u002F\u002Fcamo.githubusercontent.com\u002F8a07049df41b8a3839a3f4342f09ea8e6e7fa0065667687f04beca2d088a1dca\u002F68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f32623266393030653361633066353535316462646537323864336262343935343f733d393626643d6d6d26723d67\">\u003Cimg alt=\"Muhammad Rehan Saeed\" height=\"40\" width=\"40\" src=\"https:\u002F\u002Fcamo.githubusercontent.com\u002F8a07049df41b8a3839a3f4342f09ea8e6e7fa0065667687f04beca2d088a1dca\u002F68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f32623266393030653361633066353535316462646537323864336262343935343f733d393626643d6d6d26723d67\" \u002F>\u003C\u002Fa> \u003Cstrong>\u003Ca rel=\"nofollow noopener noreferrer\" target=\"_blank\" href=\"https:\u002F\u002Frehansaeed.com\u002F\">Muhammad Rehan Saeed\u003C\u002Fa>\u003C\u002Fstrong> commented on \u003Cstrong>2017-04-08 16:40:34\u003C\u002Fstrong>\u003C\u002Fp>\n\u003Cblockquote>\n\u003Cp>I totally understand the SRP and the IOC Concept behind this, but whats then the purpose of the Controller? Besides declaring The Routes? I mean in a more reallife Example?\u003C\u002Fp>\n\u003C\u002Fblockquote>\n\u003Cp>I think of a controller as a kind of specialized interface for HTTP or maybe a better way to describe it would be a contract. It has all your routes, caching and authorization attributes etc. It defines the public contract for how you want to do HTTP.\u003C\u002Fp>\n\u003Cp>In an imaginary world where each action method was turned into an action command class, it'd be quite difficult to get a quick overview of all of your HTTP endpoints, although such an architecture might be cool.\u003C\u002Fp>","2020-05-12T09:51:42Z",{"login":216,"avatar_url":217,"html_url":218},{"url":245,"total_count":221,"+1":221,"-1":221,"laugh":221,"hooray":221,"confused":221,"heart":221,"rocket":221,"eyes":221},"https:\u002F\u002Fapi.github.com\u002Frepos\u002FRehanSaeed\u002Frehansaeed.github.io\u002Fissues\u002Fcomments\u002F627236510\u002Freactions",{"id":247,"html_url":248,"body_html":249,"created_at":250,"user":251,"reactions":252},627236576,"https:\u002F\u002Fgithub.com\u002FRehanSaeed\u002Frehansaeed.github.io\u002Fissues\u002F57#issuecomment-627236576","\n\u003Cp>\u003Ca target=\"_blank\" rel=\"nofollow noopener noreferrer\" href=\"https:\u002F\u002Fcamo.githubusercontent.com\u002Fd9eeee4c752f49ad04d87c80ac4362d5c5426125f8cf3c37b10ef969efb01470\u002F68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f37653536356236663434313936396664616434646564303332316665336637353f733d393626643d6d6d26723d67\">\u003Cimg alt=\"Adie\" height=\"40\" width=\"40\" src=\"https:\u002F\u002Fcamo.githubusercontent.com\u002Fd9eeee4c752f49ad04d87c80ac4362d5c5426125f8cf3c37b10ef969efb01470\u002F68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f37653536356236663434313936396664616434646564303332316665336637353f733d393626643d6d6d26723d67\" \u002F>\u003C\u002Fa> \u003Cstrong>Adie\u003C\u002Fstrong> commented on \u003Cstrong>2017-04-09 15:50:02\u003C\u002Fstrong>\u003C\u002Fp>\n\u003Cp>Nice idea, better sample with asp identity would be nice\u003C\u002Fp>","2020-05-12T09:51:49Z",{"login":216,"avatar_url":217,"html_url":218},{"url":253,"total_count":221,"+1":221,"-1":221,"laugh":221,"hooray":221,"confused":221,"heart":221,"rocket":221,"eyes":221},"https:\u002F\u002Fapi.github.com\u002Frepos\u002FRehanSaeed\u002Frehansaeed.github.io\u002Fissues\u002Fcomments\u002F627236576\u002Freactions",{"id":255,"html_url":256,"body_html":257,"created_at":258,"user":259,"reactions":260},627236633,"https:\u002F\u002Fgithub.com\u002FRehanSaeed\u002Frehansaeed.github.io\u002Fissues\u002F57#issuecomment-627236633","\n\u003Cp>\u003Ca target=\"_blank\" rel=\"nofollow noopener noreferrer\" href=\"https:\u002F\u002Fcamo.githubusercontent.com\u002F8a07049df41b8a3839a3f4342f09ea8e6e7fa0065667687f04beca2d088a1dca\u002F68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f32623266393030653361633066353535316462646537323864336262343935343f733d393626643d6d6d26723d67\">\u003Cimg alt=\"Muhammad Rehan Saeed\" height=\"40\" width=\"40\" src=\"https:\u002F\u002Fcamo.githubusercontent.com\u002F8a07049df41b8a3839a3f4342f09ea8e6e7fa0065667687f04beca2d088a1dca\u002F68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f32623266393030653361633066353535316462646537323864336262343935343f733d393626643d6d6d26723d67\" \u002F>\u003C\u002Fa> \u003Cstrong>\u003Ca rel=\"nofollow noopener noreferrer\" target=\"_blank\" href=\"https:\u002F\u002Frehansaeed.com\u002F\">Muhammad Rehan Saeed\u003C\u002Fa>\u003C\u002Fstrong> commented on \u003Cstrong>2017-04-09 16:03:11\u003C\u002Fstrong>\u003C\u002Fp>\n\u003Cblockquote>\n\u003Cp>Nice idea, better sample with asp identity would be nice\u003C\u002Fp>\n\u003C\u002Fblockquote>\n\u003Cp>Agreed. ASP.NET Identity is a mess and a prime example of code that could use the command pattern. Not enough time in my day to show that though, so that's an exercise for the reader.\u003C\u002Fp>","2020-05-12T09:51:56Z",{"login":216,"avatar_url":217,"html_url":218},{"url":261,"total_count":221,"+1":221,"-1":221,"laugh":221,"hooray":221,"confused":221,"heart":221,"rocket":221,"eyes":221},"https:\u002F\u002Fapi.github.com\u002Frepos\u002FRehanSaeed\u002Frehansaeed.github.io\u002Fissues\u002Fcomments\u002F627236633\u002Freactions",{"id":263,"html_url":264,"body_html":265,"created_at":266,"user":267,"reactions":268},627236703,"https:\u002F\u002Fgithub.com\u002FRehanSaeed\u002Frehansaeed.github.io\u002Fissues\u002F57#issuecomment-627236703","\n\u003Cp>\u003Ca target=\"_blank\" rel=\"nofollow noopener noreferrer\" href=\"https:\u002F\u002Fcamo.githubusercontent.com\u002F216c09e3d7f5b502fc6a61fff1d4f717bb4cb8dc3eac735fccfc9f8a149b6ae0\u002F68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f63386635343033656537326664393763623836363432613333363337616463333f733d393626643d6d6d26723d67\">\u003Cimg alt=\"Paul\" height=\"40\" width=\"40\" src=\"https:\u002F\u002Fcamo.githubusercontent.com\u002F216c09e3d7f5b502fc6a61fff1d4f717bb4cb8dc3eac735fccfc9f8a149b6ae0\u002F68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f63386635343033656537326664393763623836363432613333363337616463333f733d393626643d6d6d26723d67\" \u002F>\u003C\u002Fa> \u003Cstrong>\u003Ca rel=\"nofollow noopener noreferrer\" target=\"_blank\" href=\"http:\u002F\u002Fpaulwheeler.com\u002F\">Paul\u003C\u002Fa>\u003C\u002Fstrong> commented on \u003Cstrong>2017-04-11 14:38:04\u003C\u002Fstrong>\u003C\u002Fp>\n\u003Cp>I use Jimmy Bogard's \u003Ca target=\"_blank\" rel=\"nofollow noopener noreferrer\" href=\"https:\u002F\u002Fgithub.com\u002Fjbogard\u002FMediatR\">MediatR\u003C\u002Fa> project to accomplish a similar purpose where controllers simply execute commands and queries. I love that pattern!\u003C\u002Fp>\n\u003Cdiv>\u003Cpre>\u003Cspan>public\u003C\u002Fspan> \u003Cspan>class\u003C\u002Fspan> \u003Cspan>Ping\u003C\u002Fspan> \u003Cspan>:\u003C\u002Fspan> \u003Cspan>IRequest\u003C\u002Fspan>\n\u003Cspan>{\u003C\u002Fspan>\n    \u003Cspan>public\u003C\u002Fspan> \u003Cspan>string\u003C\u002Fspan> \u003Cspan>Name\u003C\u002Fspan> \u003Cspan>{\u003C\u002Fspan> \u003Cspan>get\u003C\u002Fspan>\u003Cspan>;\u003C\u002Fspan> \u003Cspan>set\u003C\u002Fspan>\u003Cspan>;\u003C\u002Fspan> \u003Cspan>}\u003C\u002Fspan>\n\n    \u003Cspan>public\u003C\u002Fspan> \u003Cspan>class\u003C\u002Fspan> \u003Cspan>Pong\u003C\u002Fspan> \n    \u003Cspan>{\u003C\u002Fspan>\n        \u003Cspan>public\u003C\u002Fspan> \u003Cspan>string\u003C\u002Fspan> \u003Cspan>Message\u003C\u002Fspan> \u003Cspan>{\u003C\u002Fspan> \u003Cspan>get\u003C\u002Fspan>\u003Cspan>;\u003C\u002Fspan> \u003Cspan>set\u003C\u002Fspan>\u003Cspan>;\u003C\u002Fspan> \u003Cspan>}\u003C\u002Fspan>\n    \u003Cspan>}\u003C\u002Fspan>\n\n    \u003Cspan>internal\u003C\u002Fspan> \u003Cspan>class\u003C\u002Fspan> \u003Cspan>Handler\u003C\u002Fspan> \u003Cspan>:\u003C\u002Fspan> \u003Cspan>IRequestHandler\u003C\u002Fspan> \n    \u003Cspan>{\u003C\u002Fspan>     \n        \u003Cspan>public\u003C\u002Fspan> \u003Cspan>Pong\u003C\u002Fspan> \u003Cspan>Handle\u003C\u002Fspan>\u003Cspan>(\u003C\u002Fspan>\u003Cspan>Ping\u003C\u002Fspan> \u003Cspan>request\u003C\u002Fspan>\u003Cspan>)\u003C\u002Fspan>\n        \u003Cspan>{\u003C\u002Fspan>\n            \u003Cspan>return\u003C\u002Fspan> \u003Cspan>new\u003C\u002Fspan> \u003Cspan>Pong\u003C\u002Fspan> \u003Cspan>{\u003C\u002Fspan> \n                \u003Cspan>Message\u003C\u002Fspan> \u003Cspan>=\u003C\u002Fspan> \u003Cspan>\"Ping: \"\u003C\u002Fspan> \u003Cspan>+\u003C\u002Fspan> \u003Cspan>request\u003C\u002Fspan>\u003Cspan>.\u003C\u002Fspan>\u003Cspan>Name\u003C\u002Fspan>\n            \u003Cspan>}\u003C\u002Fspan>\u003Cspan>;\u003C\u002Fspan>\n        \u003Cspan>}\u003C\u002Fspan>\n    \u003Cspan>}\u003C\u002Fspan>\n\u003Cspan>}\u003C\u002Fspan>\u003C\u002Fpre>\u003C\u002Fdiv>","2020-05-12T09:52:04Z",{"login":216,"avatar_url":217,"html_url":218},{"url":269,"total_count":221,"+1":221,"-1":221,"laugh":221,"hooray":221,"confused":221,"heart":221,"rocket":221,"eyes":221},"https:\u002F\u002Fapi.github.com\u002Frepos\u002FRehanSaeed\u002Frehansaeed.github.io\u002Fissues\u002Fcomments\u002F627236703\u002Freactions",{"id":271,"html_url":272,"body_html":273,"created_at":274,"user":275,"reactions":276},627236765,"https:\u002F\u002Fgithub.com\u002FRehanSaeed\u002Frehansaeed.github.io\u002Fissues\u002F57#issuecomment-627236765","\n\u003Cp>\u003Ca target=\"_blank\" rel=\"nofollow noopener noreferrer\" href=\"https:\u002F\u002Fcamo.githubusercontent.com\u002F8d9a321c57824c2adb0d67cb38265ca241897d2845248019d34511040a96cbe5\u002F68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f31656233316537616161353833663361323036623839373365653335326131353f733d393626643d6d6d26723d67\">\u003Cimg alt=\"Theo Albers\" height=\"40\" width=\"40\" src=\"https:\u002F\u002Fcamo.githubusercontent.com\u002F8d9a321c57824c2adb0d67cb38265ca241897d2845248019d34511040a96cbe5\u002F68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f31656233316537616161353833663361323036623839373365653335326131353f733d393626643d6d6d26723d67\" \u002F>\u003C\u002Fa> \u003Cstrong>Theo Albers\u003C\u002Fstrong> commented on \u003Cstrong>2017-04-13 09:14:44\u003C\u002Fstrong>\u003C\u002Fp>\n\u003Cp>I have used this pattern as well to keep the API controller lean. I decided to move the \"protocol\" out of the command and into the controller action. So the command returns an object and the controller action returns the wire result \u003Ccode>NotFoundResult\u003C\u002Fcode>\u002F\u003Ccode>OkObjectResult\u003C\u002Fcode>.\u003C\u002Fp>\n\u003Cp>The question that keeps spinning in my head: why not create \u003Ccode>ApiControllers\u003C\u002Fcode> with a single method? So instead of \u003Ccode>RocketController\u003C\u002Fcode> have \u003Ccode>RocketGetController\u003C\u002Fcode>, \u003Ccode>RocketLaunchController\u003C\u002Fcode>. That way the controller turns into a command\u002Faction.\u003C\u002Fp>","2020-05-12T09:52:11Z",{"login":216,"avatar_url":217,"html_url":218},{"url":277,"total_count":221,"+1":221,"-1":221,"laugh":221,"hooray":221,"confused":221,"heart":221,"rocket":221,"eyes":221},"https:\u002F\u002Fapi.github.com\u002Frepos\u002FRehanSaeed\u002Frehansaeed.github.io\u002Fissues\u002Fcomments\u002F627236765\u002Freactions",{"id":279,"html_url":280,"body_html":281,"created_at":282,"user":283,"reactions":284},627236832,"https:\u002F\u002Fgithub.com\u002FRehanSaeed\u002Frehansaeed.github.io\u002Fissues\u002F57#issuecomment-627236832","\n\u003Cp>\u003Ca target=\"_blank\" rel=\"nofollow noopener noreferrer\" href=\"https:\u002F\u002Fcamo.githubusercontent.com\u002F24f3f48bb34e5125e08510d76c593f04e7222ab3e88517bed2a9cd52ff5dde70\u002F68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f66626238633139656161623662623734356461663263333032616537663337393f733d393626643d6d6d26723d67\">\u003Cimg alt=\"Juan Perez\" height=\"40\" width=\"40\" src=\"https:\u002F\u002Fcamo.githubusercontent.com\u002F24f3f48bb34e5125e08510d76c593f04e7222ab3e88517bed2a9cd52ff5dde70\u002F68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f66626238633139656161623662623734356461663263333032616537663337393f733d393626643d6d6d26723d67\" \u002F>\u003C\u002Fa> \u003Cstrong>Juan Perez\u003C\u002Fstrong> commented on \u003Cstrong>2017-04-18 17:31:38\u003C\u002Fstrong>\u003C\u002Fp>\n\u003Cblockquote>\n\u003Cp>I think of a controller as a kind of specialized interface for HTTP or maybe a better way to describe it would be a contract. It has all your routes, caching and authorization attributes etc. It defines the public contract for how you want to do HTTP.\u003C\u002Fp>\n\u003Cp>In an imaginary world where each action method was turned into an action command class, it'd be quite difficult to get a quick overview of all of your HTTP endpoints, although such an architecture might be cool.\u003C\u002Fp>\n\u003C\u002Fblockquote>\n\u003Cp>I do not totally agree. If you organize the commands in folder or namespaces and use names related to HTTP methods, it could be better and simpler. It is almost like a class for each action.\u003C\u002Fp>\n\u003Cp>We could create controllers that implement command interface and we could avoid all these ugly Lazy fields.\u003C\u002Fp>","2020-05-12T09:52:18Z",{"login":216,"avatar_url":217,"html_url":218},{"url":285,"total_count":221,"+1":221,"-1":221,"laugh":221,"hooray":221,"confused":221,"heart":221,"rocket":221,"eyes":221},"https:\u002F\u002Fapi.github.com\u002Frepos\u002FRehanSaeed\u002Frehansaeed.github.io\u002Fissues\u002Fcomments\u002F627236832\u002Freactions",{"id":287,"html_url":288,"body_html":289,"created_at":290,"user":291,"reactions":292},627236897,"https:\u002F\u002Fgithub.com\u002FRehanSaeed\u002Frehansaeed.github.io\u002Fissues\u002F57#issuecomment-627236897","\n\u003Cp>\u003Ca target=\"_blank\" rel=\"nofollow noopener noreferrer\" href=\"https:\u002F\u002Fcamo.githubusercontent.com\u002F8a07049df41b8a3839a3f4342f09ea8e6e7fa0065667687f04beca2d088a1dca\u002F68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f32623266393030653361633066353535316462646537323864336262343935343f733d393626643d6d6d26723d67\">\u003Cimg alt=\"Muhammad Rehan Saeed\" height=\"40\" width=\"40\" src=\"https:\u002F\u002Fcamo.githubusercontent.com\u002F8a07049df41b8a3839a3f4342f09ea8e6e7fa0065667687f04beca2d088a1dca\u002F68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f32623266393030653361633066353535316462646537323864336262343935343f733d393626643d6d6d26723d67\" \u002F>\u003C\u002Fa> \u003Cstrong>\u003Ca rel=\"nofollow noopener noreferrer\" target=\"_blank\" href=\"https:\u002F\u002Frehansaeed.com\u002F\">Muhammad Rehan Saeed\u003C\u002Fa>\u003C\u002Fstrong> commented on \u003Cstrong>2017-04-21 15:32:39\u003C\u002Fstrong>\u003C\u002Fp>\n\u003Cblockquote>\n\u003Cp>I have used this pattern as well to keep the API controller lean. I decided to move the \"protocol\" out of the command and into the controller action. So the command returns an object and the controller action returns the wire result \u003Ccode>NotFoundResult\u003C\u002Fcode>\u002F\u003Ccode>OkObjectResult\u003C\u002Fcode>.\u003C\u002Fp>\n\u003Cp>The question that keeps spinning in my head: why not create \u003Ccode>ApiControllers\u003C\u002Fcode> with a single method? So instead of \u003Ccode>RocketController\u003C\u002Fcode> have \u003Ccode>RocketGetController\u003C\u002Fcode>, \u003Ccode>RocketLaunchController\u003C\u002Fcode>. That way the controller turns into a command\u002Faction.\u003C\u002Fp>\n\u003C\u002Fblockquote>\n\u003Cp>Controllers with a single action method are interesting and certainly a possible direction. I personally feel that an action method is doing two things:\u003C\u002Fp>\n\u003Col>\n\u003Cli>Defines an interface for a request.\u003C\u002Fli>\n\u003Cli>Builds and returns a response.\u003Cbr \u002F>\nThese two things go against the \u003Ca rel=\"nofollow noopener noreferrer\" target=\"_blank\" href=\"https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FSingle_responsibility_principle\">single responsibility principle\u003C\u002Fa>. When you are working on building a reponse, you don't care about the request interface (routes, auth etc.), thats all noise. A controller per action method would also make it more difficult to see all your related routes in one place. Using the command pattern, the controller just becomes a specialized interface for HTTP.\u003C\u002Fli>\n\u003C\u002Fol>","2020-05-12T09:52:24Z",{"login":216,"avatar_url":217,"html_url":218},{"url":293,"total_count":221,"+1":221,"-1":221,"laugh":221,"hooray":221,"confused":221,"heart":221,"rocket":221,"eyes":221},"https:\u002F\u002Fapi.github.com\u002Frepos\u002FRehanSaeed\u002Frehansaeed.github.io\u002Fissues\u002Fcomments\u002F627236897\u002Freactions",{"id":295,"html_url":296,"body_html":297,"created_at":298,"user":299,"reactions":300},627236974,"https:\u002F\u002Fgithub.com\u002FRehanSaeed\u002Frehansaeed.github.io\u002Fissues\u002F57#issuecomment-627236974","\n\u003Cp>\u003Ca target=\"_blank\" rel=\"nofollow noopener noreferrer\" href=\"https:\u002F\u002Fcamo.githubusercontent.com\u002F8a07049df41b8a3839a3f4342f09ea8e6e7fa0065667687f04beca2d088a1dca\u002F68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f32623266393030653361633066353535316462646537323864336262343935343f733d393626643d6d6d26723d67\">\u003Cimg alt=\"Muhammad Rehan Saeed\" height=\"40\" width=\"40\" src=\"https:\u002F\u002Fcamo.githubusercontent.com\u002F8a07049df41b8a3839a3f4342f09ea8e6e7fa0065667687f04beca2d088a1dca\u002F68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f32623266393030653361633066353535316462646537323864336262343935343f733d393626643d6d6d26723d67\" \u002F>\u003C\u002Fa> \u003Cstrong>\u003Ca rel=\"nofollow noopener noreferrer\" target=\"_blank\" href=\"https:\u002F\u002Frehansaeed.com\u002F\">Muhammad Rehan Saeed\u003C\u002Fa>\u003C\u002Fstrong> commented on \u003Cstrong>2017-04-21 15:33:18\u003C\u002Fstrong>\u003C\u002Fp>\n\u003Cblockquote>\n\u003Cp>I do not totally agree. If you organize the commands in folder or namespaces and use names related to HTTP methods, it could be better and simpler. It is almost like a class for each action.\u003C\u002Fp>\n\u003Cp>We could create controllers that implement command interface and we could avoid all these ugly Lazy fields.\u003C\u002Fp>\n\u003C\u002Fblockquote>\n\u003Cp>See my answer to Theo Albers.\u003C\u002Fp>","2020-05-12T09:52:32Z",{"login":216,"avatar_url":217,"html_url":218},{"url":301,"total_count":221,"+1":221,"-1":221,"laugh":221,"hooray":221,"confused":221,"heart":221,"rocket":221,"eyes":221},"https:\u002F\u002Fapi.github.com\u002Frepos\u002FRehanSaeed\u002Frehansaeed.github.io\u002Fissues\u002Fcomments\u002F627236974\u002Freactions",{"id":303,"html_url":304,"body_html":305,"created_at":306,"user":307,"reactions":308},627237036,"https:\u002F\u002Fgithub.com\u002FRehanSaeed\u002Frehansaeed.github.io\u002Fissues\u002F57#issuecomment-627237036","\n\u003Cp>\u003Ca target=\"_blank\" rel=\"nofollow noopener noreferrer\" href=\"https:\u002F\u002Fcamo.githubusercontent.com\u002Fbd8ecfbb9f1a881c755b1c3711ee2ac510efb53b03a5659558654d4925b1de71\u002F68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f65386263376439393264396432313435353262643562333230623639616533613f733d393626643d6d6d26723d67\">\u003Cimg alt=\"paul\" height=\"40\" width=\"40\" src=\"https:\u002F\u002Fcamo.githubusercontent.com\u002Fbd8ecfbb9f1a881c755b1c3711ee2ac510efb53b03a5659558654d4925b1de71\u002F68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f65386263376439393264396432313435353262643562333230623639616533613f733d393626643d6d6d26723d67\" \u002F>\u003C\u002Fa> \u003Cstrong>paul\u003C\u002Fstrong> commented on \u003Cstrong>2017-04-29 23:44:52\u003C\u002Fstrong>\u003C\u002Fp>\n\u003Cblockquote>\n\u003Cp>Controllers with a single action method are interesting and certainly a possible direction. I personally feel that an action method is doing two things:\u003C\u002Fp>\n\u003Col>\n\u003Cli>Defines an interface for a request.\u003C\u002Fli>\n\u003Cli>Builds and returns a response.\u003Cbr \u002F>\nThese two things go against the \u003Ca rel=\"nofollow noopener noreferrer\" target=\"_blank\" href=\"https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FSingle_responsibility_principle\">single responsibility principle\u003C\u002Fa>. When you are working on building a reponse, you don't care about the request interface (routes, auth etc.), thats all noise. A controller per action method would also make it more difficult to see all your related routes in one place. Using the command pattern, the controller just becomes a specialized interface for HTTP.\u003C\u002Fli>\n\u003C\u002Fol>\n\u003C\u002Fblockquote>\n\u003Cp>I agree with Theo that I cannot see how this approach offers any benefit over 'one action controllers' and in fact it just adds complexity. You mentioned that the controller defies the interface for the request but this is not strictly true. The route is only part of the interface. The request and response types are also a significant part of the contract and these are defined in the command. So now we have the command being responsible for some of 1) and all of 2). Just my two cents.\u003C\u002Fp>","2020-05-12T09:52:39Z",{"login":216,"avatar_url":217,"html_url":218},{"url":309,"total_count":221,"+1":221,"-1":221,"laugh":221,"hooray":221,"confused":221,"heart":221,"rocket":221,"eyes":221},"https:\u002F\u002Fapi.github.com\u002Frepos\u002FRehanSaeed\u002Frehansaeed.github.io\u002Fissues\u002Fcomments\u002F627237036\u002Freactions",{"id":311,"html_url":312,"body_html":313,"created_at":314,"user":315,"reactions":316},627237106,"https:\u002F\u002Fgithub.com\u002FRehanSaeed\u002Frehansaeed.github.io\u002Fissues\u002F57#issuecomment-627237106","\n\u003Cp>\u003Ca target=\"_blank\" rel=\"nofollow noopener noreferrer\" href=\"https:\u002F\u002Fcamo.githubusercontent.com\u002F3b30bf0ace08d58974339751ba76131cc9d88e19a29916cf98e5a351fb945bbc\u002F68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f35336437386630633038366362323333373538343933303862396236626434333f733d393626643d6d6d26723d67\">\u003Cimg alt=\"XperiAndri\" height=\"40\" width=\"40\" src=\"https:\u002F\u002Fcamo.githubusercontent.com\u002F3b30bf0ace08d58974339751ba76131cc9d88e19a29916cf98e5a351fb945bbc\u002F68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f35336437386630633038366362323333373538343933303862396236626434333f733d393626643d6d6d26723d67\" \u002F>\u003C\u002Fa> \u003Cstrong>XperiAndri\u003C\u002Fstrong> commented on \u003Cstrong>2017-07-15 15:28:28\u003C\u002Fstrong>\u003C\u002Fp>\n\u003Cp>Looks interesting however very verbose and overcomplicated.\u003Cbr \u002F>\nSolutions with MediatR look much more concise and elegant.\u003C\u002Fp>\n\u003Cp>And in my opinion your current implementation look like moving controller specific stuff to business layer.\u003C\u002Fp>","2020-05-12T09:52:45Z",{"login":216,"avatar_url":217,"html_url":218},{"url":317,"total_count":221,"+1":221,"-1":221,"laugh":221,"hooray":221,"confused":221,"heart":221,"rocket":221,"eyes":221},"https:\u002F\u002Fapi.github.com\u002Frepos\u002FRehanSaeed\u002Frehansaeed.github.io\u002Fissues\u002Fcomments\u002F627237106\u002Freactions",{"id":319,"html_url":320,"body_html":321,"created_at":322,"user":323,"reactions":324},627237164,"https:\u002F\u002Fgithub.com\u002FRehanSaeed\u002Frehansaeed.github.io\u002Fissues\u002F57#issuecomment-627237164","\n\u003Cp>\u003Ca target=\"_blank\" rel=\"nofollow noopener noreferrer\" href=\"https:\u002F\u002Fcamo.githubusercontent.com\u002F8a07049df41b8a3839a3f4342f09ea8e6e7fa0065667687f04beca2d088a1dca\u002F68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f32623266393030653361633066353535316462646537323864336262343935343f733d393626643d6d6d26723d67\">\u003Cimg alt=\"Muhammad Rehan Saeed\" height=\"40\" width=\"40\" src=\"https:\u002F\u002Fcamo.githubusercontent.com\u002F8a07049df41b8a3839a3f4342f09ea8e6e7fa0065667687f04beca2d088a1dca\u002F68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f32623266393030653361633066353535316462646537323864336262343935343f733d393626643d6d6d26723d67\" \u002F>\u003C\u002Fa> \u003Cstrong>\u003Ca rel=\"nofollow noopener noreferrer\" target=\"_blank\" href=\"https:\u002F\u002Frehansaeed.com\u002F\">Muhammad Rehan Saeed\u003C\u002Fa>\u003C\u002Fstrong> commented on \u003Cstrong>2017-07-23 12:37:56\u003C\u002Fstrong>\u003C\u002Fp>\n\u003Cblockquote>\n\u003Cp>Looks interesting however very verbose and overcomplicated.\u003Cbr \u002F>\nSolutions with MediatR look much more concise and elegant.\u003C\u002Fp>\n\u003Cp>And in my opinion your current implementation look like moving controller specific stuff to business layer.\u003C\u002Fp>\n\u003C\u002Fblockquote>\n\u003Cp>MediatR is interesting but it's another dependency, and much slower than this implementation because it uses \u003Ccode>Activator.CreateInstance()\u003C\u002Fcode>. This implementation is much simpler (a couple of interfaces used by the DI container, has zero dependencies and is as fast as it gets.\u003C\u002Fp>\n\u003Cp>I debated with myself whether the controller should return a business object or an \u003Ccode>IActionResult\u003C\u002Fcode>. I actually started with the former but settled on the latter. It makes things much simpler, it's all C# POCO's which makes unit testing a breeze.\u003C\u002Fp>","2020-05-12T09:52:52Z",{"login":216,"avatar_url":217,"html_url":218},{"url":325,"total_count":221,"+1":221,"-1":221,"laugh":221,"hooray":221,"confused":221,"heart":221,"rocket":221,"eyes":221},"https:\u002F\u002Fapi.github.com\u002Frepos\u002FRehanSaeed\u002Frehansaeed.github.io\u002Fissues\u002Fcomments\u002F627237164\u002Freactions",{"id":327,"html_url":328,"body_html":329,"created_at":330,"user":331,"reactions":332},627237208,"https:\u002F\u002Fgithub.com\u002FRehanSaeed\u002Frehansaeed.github.io\u002Fissues\u002F57#issuecomment-627237208","\n\u003Cp>\u003Ca target=\"_blank\" rel=\"nofollow noopener noreferrer\" href=\"https:\u002F\u002Fcamo.githubusercontent.com\u002F8b934faeefede6c8e8e1f225ba3467ab3af282fcb32d2c4f1a7e440c2c149934\u002F68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f39613866333738323436383065333238393831633466306436663733633231613f733d393626643d6d6d26723d67\">\u003Cimg alt=\"Manish\" height=\"40\" width=\"40\" src=\"https:\u002F\u002Fcamo.githubusercontent.com\u002F8b934faeefede6c8e8e1f225ba3467ab3af282fcb32d2c4f1a7e440c2c149934\u002F68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f39613866333738323436383065333238393831633466306436663733633231613f733d393626643d6d6d26723d67\" \u002F>\u003C\u002Fa> \u003Cstrong>Manish\u003C\u002Fstrong> commented on \u003Cstrong>2017-08-22 03:51:20\u003C\u002Fstrong>\u003C\u002Fp>\n\u003Cblockquote>\n\u003Cp>I have used this pattern as well to keep the API controller lean. I decided to move the \"protocol\" out of the command and into the controller action. So the command returns an object and the controller action returns the wire result \u003Ccode>NotFoundResult\u003C\u002Fcode>\u002F\u003Ccode>OkObjectResult\u003C\u002Fcode>.\u003C\u002Fp>\n\u003Cp>The question that keeps spinning in my head: why not create \u003Ccode>ApiControllers\u003C\u002Fcode> with a single method? So instead of \u003Ccode>RocketController\u003C\u002Fcode> have \u003Ccode>RocketGetController\u003C\u002Fcode>, \u003Ccode>RocketLaunchController\u003C\u002Fcode>. That way the controller turns into a command\u002Faction.\u003C\u002Fp>\n\u003C\u002Fblockquote>\n\u003Cp>Hello,\u003Cbr \u002F>\nHow did you do it? Can you please post sample code?\u003C\u002Fp>","2020-05-12T09:52:59Z",{"login":216,"avatar_url":217,"html_url":218},{"url":333,"total_count":221,"+1":221,"-1":221,"laugh":221,"hooray":221,"confused":221,"heart":221,"rocket":221,"eyes":221},"https:\u002F\u002Fapi.github.com\u002Frepos\u002FRehanSaeed\u002Frehansaeed.github.io\u002Fissues\u002Fcomments\u002F627237208\u002Freactions",{"id":335,"html_url":336,"body_html":337,"created_at":338,"user":339,"reactions":340},627237269,"https:\u002F\u002Fgithub.com\u002FRehanSaeed\u002Frehansaeed.github.io\u002Fissues\u002F57#issuecomment-627237269","\n\u003Cp>\u003Ca target=\"_blank\" rel=\"nofollow noopener noreferrer\" href=\"https:\u002F\u002Fcamo.githubusercontent.com\u002F3c5615198835748b0a6883906ec865eb5fc5c540e256bc7f1bdacb271ede8e78\u002F68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f35383062333162306265373137336262633437376361316436393637643837633f733d393626643d6d6d26723d67\">\u003Cimg alt=\"Aluan Haddad\" height=\"40\" width=\"40\" src=\"https:\u002F\u002Fcamo.githubusercontent.com\u002F3c5615198835748b0a6883906ec865eb5fc5c540e256bc7f1bdacb271ede8e78\u002F68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f35383062333162306265373137336262633437376361316436393637643837633f733d393626643d6d6d26723d67\" \u002F>\u003C\u002Fa> \u003Cstrong>\u003Ca rel=\"nofollow noopener noreferrer\" target=\"_blank\" href=\"http:\u002F\u002Flasi-project.org\u002F\">Aluan Haddad\u003C\u002Fa>\u003C\u002Fstrong> commented on \u003Cstrong>2018-01-20 11:13:20\u003C\u002Fstrong>\u003C\u002Fp>\n\u003Cp>While abstracting away common patterns is of course good, this overlooks the basic facilities the language already provides to accomplish this.\u003C\u002Fp>\n\u003Cp>The \u003Ccode>IAsyncCommand\u003C\u002Fcode> interfaces you have defined introduce unnecessary complexity and represent a barrier to simple composition. In particular, the whole pattern reeks of Java and the complexity and ugliness inherent in its abhorrent SAM types.\u003C\u002Fp>\n\u003Cp>This is C#, we don't need nonsensical, SAM types, we have delegates.\u003C\u002Fp>","2020-05-12T09:53:06Z",{"login":216,"avatar_url":217,"html_url":218},{"url":341,"total_count":221,"+1":221,"-1":221,"laugh":221,"hooray":221,"confused":221,"heart":221,"rocket":221,"eyes":221},"https:\u002F\u002Fapi.github.com\u002Frepos\u002FRehanSaeed\u002Frehansaeed.github.io\u002Fissues\u002Fcomments\u002F627237269\u002Freactions",{"id":343,"html_url":344,"body_html":345,"created_at":346,"user":347,"reactions":351},699198928,"https:\u002F\u002Fgithub.com\u002FRehanSaeed\u002Frehansaeed.github.io\u002Fissues\u002F57#issuecomment-699198928","\u003Cp>Instead of your lazy stuff use FromServicesAttribute for each action\u002Fcommand\u003C\u002Fp>","2020-09-25T22:52:44Z",{"login":348,"avatar_url":349,"html_url":350},"TarasKuz","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F32145357?v=4","https:\u002F\u002Fgithub.com\u002FTarasKuz",{"url":352,"total_count":221,"+1":221,"-1":221,"laugh":221,"hooray":221,"confused":221,"heart":221,"rocket":221,"eyes":221},"https:\u002F\u002Fapi.github.com\u002Frepos\u002FRehanSaeed\u002Frehansaeed.github.io\u002Fissues\u002Fcomments\u002F699198928\u002Freactions",{"id":354,"html_url":355,"body_html":356,"created_at":357,"user":358,"reactions":359},699496418,"https:\u002F\u002Fgithub.com\u002FRehanSaeed\u002Frehansaeed.github.io\u002Fissues\u002F57#issuecomment-699496418","\u003Cblockquote>\n\u003Cp>Instead of your lazy stuff use FromServicesAttribute for each action\u002Fcommand\u003C\u002Fp>\n\u003C\u002Fblockquote>\n\u003Cp>\u003Ca target=\"_blank\" rel=\"nofollow noopener noreferrer\" href=\"https:\u002F\u002Fgithub.com\u002FTarasKuz\">@TarasKuz\u003C\u002Fa> Agreed, soon after I wrote this, I switched to using \u003Ccode>[FromServices]\u003C\u002Fcode>.\u003C\u002Fp>","2020-09-26T13:33:43Z",{"login":216,"avatar_url":217,"html_url":218},{"url":360,"total_count":361,"+1":361,"-1":221,"laugh":221,"hooray":221,"confused":221,"heart":221,"rocket":221,"eyes":221},"https:\u002F\u002Fapi.github.com\u002Frepos\u002FRehanSaeed\u002Frehansaeed.github.io\u002Fissues\u002Fcomments\u002F699496418\u002Freactions",1,"2017-04-08T00:00:00+00:00",null,"Move your ASP.NET Core MVC action method logic into lazily loaded commands using the command pattern, to reduce Controller complexity.","md",[367,368,369,370,371],{"depth":361,"value":58},{"depth":361,"value":97},{"depth":361,"value":122},{"depth":361,"value":169},{"depth":361,"value":183},"\u002Fimages\u002Fhero\u002FASP.NET-Core-Lazy-Command-Pattern-1366x768.png",{},"\u002Fasp-net-core-lazy-command-pattern\u002F",true,"posts\u002F2017\u002Fasp-net-core-lazy-command-pattern\u002Findex",[378,379,380,381,382,195,383,384,385],".NET",".NET Core","ASP.NET Core","ASP.NET MVC",".NET Boxed","C#","Command Pattern","Lazy",4,1792790625835]