如何创建动态命令对象

时间:2016-12-11 19:57:35

标签: c# oop design-patterns

我创建了几个代表我车的命令的类:

  • PaintCommand
  • RefuelCommand

此类实现了ICommand接口,包含Execute(Car c)方法。

示例:

    public class RefuelCommand : ICommand
{
    public RefuelCommand()
    {
    }


    public void Execute(Car car)
    {
        car.SetFuel(100);
    }
}

我使用命令模式来初始化命令。

现在,我希望能够在不更改代码的情况下添加新的Command

我现在想要Change Name command

有没有人有想法?

我的想法:

创建一个描述class命令的xml文件。 (Name,Param)并从中生成一个新的Command对象。

2 个答案:

答案 0 :(得分:0)

也许您需要实现一个可以接受委托作为参数的通用命令。

也就是说,在运行时可以根据需要添加任意数量的命令:

public interface ICommand
{
     void Execute(Car car);
}

public class GenericCommand : ICommand
{
     public GenericCommand(Action<Car> executePredicate)
     {
           Contract.Requires(executePredicate != null);

           ExecutePredicate = executePredicate;
     }

     private Action<Car> ExecutePredicate { get; }

     public void Execute(Car car) => ExecutePredicate(car);
}

因此,您将能够按如下方式创建命令:

ICommand command1 = new GenericCommand
(
    car =>
    {
        // Do stuff here with a given car
    }
);

ICommand command2 = new GenericCommand
(
    car =>
    {
        // Do stuff here with a given car
    }
);

ICommand commandN = new GenericCommand
(
    car =>
    {
        // Do stuff here with a given car
    }
);

答案 1 :(得分:0)

您可以使用T4模板生成代码。例如,创建此XML文件并将其放在bin文件夹中:

<?xml version="1.0" encoding="utf-8" ?>  
<command>  
  <name>NameCommand</name>
  <param>Car</param>  
</command> 

现在为项目添加一个新项目:

  1. 右键单击解决方案资源管理器中的项目节点&gt;添加&gt;新商品&gt; Visual C#项目并选择文本模板。
  2. 为您的模板命名。我称之为ICommandGenerator。
  3. 在模板中放置以下代码:

    <#@ output extension=".cs" #>  
    <#@ assembly name="System.Xml"#>  
    <#@ import namespace="System.Xml" #> 
    <#@ import namespace="System" #> 
    <#@ template debug="false" hostspecific="true" language="C#" #>  
    <#  
    XmlDocument doc = new XmlDocument();  
    // Replace this file path with yours:  
    doc.Load(Host.ResolvePath(@"bin\debug\NameCommand.xml"));  
    var className = doc.GetElementsByTagName("name")[0].InnerText;
    var paramName = doc.GetElementsByTagName("param")[0].InnerText;
    #>
    namespace ConsoleApplication1
    {
        public partial class <#= className #> 
        {
            public <#= className #>() {}
    
            public void Execute(<#= paramName #> p)
            {
                // your code here...
            }
        }
    }
    

    右键单击解决方案资源管理器中的TT文件,然后选择“运行自定义工具”。它将使用XML文件生成下面的类。此类将是TT文件的子节点,因此展开TT文件,您将看到此类:

    namespace ConsoleApplication1
    {
        public partial class NameCommand 
        {
            public NameCommand() {}
    
            public void Execute(Car p)
            {
                // your code here...
            }
        }
    }
    

    您可以修改TT文件以使用其他命名空间而不是ConsoleApplication。您甚至可以在XML文件中放入一堆Command类型,并循环遍历所有类型并生成许多类。您可以阅读有关T4模板here的更多信息。

    这是EF使用数据库优先技术生成类的方法,其中您通过使用连接字符串将其指向数据库来指示EF。 EF然后分析您的数据库并最终在项目中放置.tt。