вторник, 9 ноября 2010 г.

C# custom tool file generation based on C# template file

Download sources and vsix from CompileGenerator.Codeplex.com

C# custom tool file generation based on C# template file. Write C# Code wich will be converted to another more detailed, specific C# code.
Features
- Build-in VS2010 .cs file Syntax highlighting and IntelliSense in template
- No need to learn new language nor syntax for template writers. C# your best friend here.
- Modifying generation code without restarting VS (code compiled in another domain)
- Code that writes code, it’s fun
- Preprocessed t4 templates for code generator
- No XML
- No more Dependency Property mess in your code
How it’s work
1. Add a new simple .cs file into your project

2. Write code that may describe some other code you need right here in your project (Dependency Properties, DTO or CQRS Commands for example)

using Xiety.DtoGenerator;

public class Nodes : DtoData
{
    public void Run()
    {
        Namespace("Xiety.GenerationSample");

        Class("TableNode""QueryNode")
            .Property("string""TableName");

        Class("OnNode")
            .ListProperty("ExpressionNode""Expressions");

        Class("QueryNode", abstr: true)
            .Property("QueryNode""Query")
            .Property("String""Alias");

        Class("ExpressionNode")
            .Property("string""Content");

        Class("JoinNode""QueryNode")
            .Property("OnNode""On")
            .Property("QueryNode""Left")
            .Property("QueryNode""Right");

        Class("FilterNode""QueryNode")
            .Property("WhereNode""Where");

        Class("WhereNode")
            .ListProperty("ExpressionNode""Expressions");
    }
}
3. Change custom tool settings of your file

4. Save your file and immediately get the new .cs file right in place with generated results

using System;
using System.Collections.Generic;

namespace Xiety.GenerationSample
{
    public class TableNode : QueryNode
    {
        public string TableName { getset; }

    }

    public class OnNode
    {
        public IList<ExpressionNode> Expressions { getset; }

        public OnNode()
        {
            Expressions = new List<ExpressionNode>();
        }
    }

    public abstract class QueryNode
    {
        public QueryNode Query { getset; }
        public String Alias { getset; }

    }

    public class ExpressionNode
    {
        public string Content { getset; }

    }

    public class JoinNode : QueryNode
    {
        public OnNode On { getset; }
        public QueryNode Left { getset; }
        public QueryNode Right { getset; }

    }

    public class FilterNode : QueryNode
    {
        public WhereNode Where { getset; }

    }

    public class WhereNode
    {
        public IList<ExpressionNode> Expressions { getset; }

        public WhereNode()
        {
            Expressions = new List<ExpressionNode>();
        }
    }

}

5. Tune your generator template and code to produce different results
<#@ template language="C#" #>
<#@ import namespace="System.Linq" #>
using System;
using System.Collections.Generic;

<# if (NotEmpty(Data.FileNamespace)) { #>
namespace 
<#= Data.FileNamespace #>
{
<# } #>
<# foreach (var cls in Data.Classes) { #>
    public
<#= If(cls.Abstract, " abstract"#> class <#= cls.Name #><#= IfNotNull(cls.Extends, " : {0}"#>
    {
<# foreach (var property in cls.Properties) { #>
        public 
<#= property.TypeName #> <#= property.Name #> { get; set; }
<# } #>
<# foreach (var property in cls.ListProperties) { #>
        public IList<
<#= property.TypeName #><#= property.Name #> { get; set; }
<# } #>

<# if (cls.ListProperties.Any()) { #>
        public 
<#= cls.Name #>()
        {
<# foreach (var property in cls.ListProperties) { #>
            
<#= property.Name #> = new List<<#= property.TypeName #>>();
<# } #>
        }
<# }//constructor #>
    }

<# } #>
<# if (NotEmpty(Data.FileNamespace)) { #>
}
<# } #>

C# DSL Language to describe template

using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;

namespace Xiety.DtoGenerator
{
    public class DtoData
    {
        public string FileNamespace { getset; }
        public List<ClassNode> Classes { getset; }

        public DtoData()
        {
            Classes = new List<ClassNode>();
        }

        public void Namespace(string nspace)
        {
            this.FileNamespace = nspace;
        }

        public ClassNode Class(string name, string extends = nullbool abstr = false)
        {

            var cls = new ClassNode(name, extends, abstr);
            this.Classes.Add(cls);
            return cls;
        }
    }

    public class ClassNode
    {
        public bool Abstract { getset; }
        public string Extends { getset; }
        public string Name { getset; }

        public List<PropertyNode> Properties { getset; }
        public List<ListPropertyNode> ListProperties { getset; }

        public ClassNode()
        {
            this.Properties = new List<PropertyNode>();
            this.ListProperties = new List<ListPropertyNode>();
        }

        public ClassNode(string name, string extends, bool abstr)
            : this()
        {

            this.Name = name;
            this.Extends = extends;
            this.Abstract = abstr;
        }

        public ClassNode Property(string type, string name)
        {

            var property = new PropertyNode(type, name);
            this.Properties.Add(property);
            return this;
        }

        public ClassNode ListProperty(string type, string name)
        {

            var property = new ListPropertyNode(type, name);
            this.ListProperties.Add(property);
            return this;
        }
    }

    public class PropertyNode
    {
        public string TypeName { getset; }
        public string Name { getset; }

        public PropertyNode(string typeName, string name)
        {

            this.TypeName = typeName;
            this.Name = name;
        }
    }

    public class ListPropertyNode
    {
        public string TypeName { getset; }
        public string Name { getset; }

        public ListPropertyNode(string typeName, string name)
        {

            this.TypeName = typeName;
            this.Name = name;
        }
    }
}

Download sources and vsix from CompileGenerator.Codeplex.com

Комментариев нет:

Отправить комментарий