0

I created a few classes that represent Commands to my car:

  • PaintCommand.
  • RefuelCommand.

This classes implemented ICommand Interface, Contain Execute(Car c) method.

Example:

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


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

I used command patterns to init the commands.

Now, i want to be able to add new Command without change the code.

Assume i want now Change Name command

Does anyone have an idea?

My Idea:

Create a xml file that describe the class command. (Name, Param) and generate from it a new Command object.

maz
  • 515
  • 2
  • 8
  • 22
  • Your question is unclear; are you asking about how to deserialise objects from XML? If so, have a look at these questions: http://stackoverflow.com/questions/10518372/how-to-deserialize-xml-to-object and http://stackoverflow.com/questions/364253/how-to-deserialize-xml-document – Ben Cottrell Dec 11 '16 at 20:40

2 Answers2

0

Maybe you need to implement a generic command which could accept a delegate as argument.

That is, it'll be possible to add as many commands as needed during run-time:

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);
}

Thus, you'll be able to create commands as follows:

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
    }
);
Matías Fidemraizer
  • 63,804
  • 18
  • 124
  • 206
0

You can generate the code using T4 templates. For example, create this XML file and place it in your bin folder:

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

Now add a new item to your project:

  1. Right click project node in solution explorer > Add > New Item > Visual C# Items and select Text Template.
  2. Give your template a name. I called it ICommandGenerator.

In the template place the following code:

<#@ 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...
        }
    }
}

Right click on the TT file in solution explorer and select Run Custom Tool. It will generate the class below using the XML file. This class will be a child node of the TT file so expand the TT file and you will see this class:

namespace ConsoleApplication1
{
    public partial class NameCommand 
    {
        public NameCommand() {}

        public void Execute(Car p)
        {
            // your code here...
        }
    }
}

You can modify the TT file to use another namespace instead of the ConsoleApplication. You can even put a bunch of Command types in the XML file and loop through all of them and generate many classes. You can read more about T4 templates here.

This is how EF generates classes using database first technique wherein you instruct EF by pointing it towards a database using a connection string. EF then analyses your database and eventually places a .tt in your project.

CodingYoshi
  • 25,467
  • 4
  • 62
  • 64