Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Code generator, plug-in based

27 Dec 2006 1  
Another code generator, plug-in based.

Sample Image

Introduction

This article will show you how to create a simple code generator, plug-in based. A code generator can hugely improve your productivity as it does the repetitive work for you. Nowadays, computer systems are becoming bigger and complex. I worked on an ERP project in which there was about 470 tables. Suppose you have to map all the 470 tables to C# classes by hand. It is just a waste of time. Let the code generator work for you.

Background

The core of the code generator is the API (Application Programming Interface) in which is defined its skeleton. In order to write plug-ins for the code generator, you must implement or inherit the interfaces or basic classes, respectively. See the diagram below for better elucidation.

Classes and interfaces responsibilities

The IConnector interface defines the contract for a connector plug-in. An implementation class is responsible for connecting to a data source and returning an ISchema implementation based on that structure. The purpose of the ISchema, ITable, and IRelationShip is abstracting a relational data structure. The ILanguageParser defines the contract for a language parser plug-in. An implementation class is responsible for parsing an ISchema implementation. The IPluginManager defines a contract for managing a collection of IPlugin implementations as you can see in the diagram above.

Using the code

A full code implementation is provided with the demonstration project. In order to improve your understanding of how the code works, I will show you a high level code implementation.

namespace CSharpParser
{
    public class CSharpParser : Worker.Core.API.ILanguageParser
    {
        StringBuilder sb = new StringBuilder();
        public string Parse(Worker.Core.API.ISchema schema)
        {
            //here you should write code to iterate 

            //throw the table and relationship collection. 

        }
    }
}

namespace SimpleConnector
{
    public class SimpleConnector : Worker.Core.API.IConnector
    {
        public bool Connect(string pconnectionString)
        {
        //here you should write code for data source connection.

        }
        public Worker.Core.API.ISchema Buildschema(String pdataBase)
        {
        //here you should write code for abstracting a relational data structure

        }
    }
}

namespace SimplePluginManager
{
    public class SimplePluginManager : Worker.Core.API.IPluginManager
    {
        public List GetAll()
        {
        }
        public object Find(string name)
        {
        //here you should write code to find a plug in

        }
        public object Plug(IPlugin plugin,String type)
        { 
            //here you should write code in order to bind 

            //the interface and its implementation.

        }
        public bool Register(IPlugin info)
        {
        //here you should write code for registering a plugin.

        }
        public void Persist(String source)
        {
        //here you should write code for persisting a plugin.

        }
        public void Load(String source)
        {
        //here you should write code for loading persisted plugins.

        }
    }
}

//Sample code usage

//Registering the plugins

IPluginManager pluginManager = 
  (IPluginManager)new SimplePluginManager.SimplePluginManager();
IPlugin pluginConnector = new Plugin();
pluginConnector.Name = "MySqlConnector";
pluginConnector.Path = @"MySqlPlugin\SimpleConnector.dll";
pluginConnector.Version = "1.0";
pluginManager.Register(pluginConnector);
IPlugin pluginCSharp = new Plugin();
pluginCSharp.Name = "CSharpParser";
pluginCSharp.Path = @"CsharpPlugin\CSharpParser.dll";
pluginCSharp.Version = "1.0";
pluginManager.Register(pluginCSharp);

//Finding registered plugins

IPlugin fpluginConnector = 
  (IPlugin)pluginManager.Find("MySqlConnector");
IPlugin fpluginParser = (IPlugin)pluginManager.Find("CSharpParser");

//Connecting to a data source

IConnector con = 
  (IConnector)pluginManager.Plug(fpluginConnector,"IConnector");
con.Connect("ConnectionString");
//Creating the schema from a data source

Ischema schema = con.Buildschema("DataBaseName");
//generating the code

ILanguageParser parser = 
  (ILanguageParser)pluginManager.Plug(fpluginParser, "ILanguageParser");
this.richTextBox1.Text = parser.Parse(schema);

Conclusion

The Worker.API can be used to create code generators for any language. All you have to do is to create a plug-in and register it in a PluginManager. You can have your staff working in parallel. One writes the Connector while the other writes the LanguageParser.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here