Adding a DataSourceAttribute through CodeDom


using System;
using System.CodeDom;
using System.CodeDom.Compiler;
using Microsoft.CSharp;
using Microsoft.VisualBasic;

namespace AttributeCodeGenDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            //using (CodeDomProvider codeProvider = new VBCodeProvider())
            using (CodeDomProvider codeProvider = new CSharpCodeProvider())
            {
                // Create namespace to hold new class
                CodeNamespace demoCodeNamespace = new CodeNamespace("Troolean.CodeDom.Demo");
                // Create using statements
                demoCodeNamespace.Imports.Add(new CodeNamespaceImport("Microsoft.VisualStudio.TestTools.UnitTesting"));
                demoCodeNamespace.Imports.Add(new CodeNamespaceImport("System"));

                // Create class
                CodeTypeDeclaration fooBarCodeTypeDecl = new CodeTypeDeclaration("FooBar")
                {
                    IsClass = true
                };

                // Add class to namespace
                demoCodeNamespace.Types.Add(fooBarCodeTypeDecl);

                // Decorate class with TestClass attribute
                fooBarCodeTypeDecl.CustomAttributes.Add(new CodeAttributeDeclaration("TestClass"));

                // Create a new method
                CodeMemberMethod executeCodeMember = new CodeMemberMethod()
                {
                    Name = "Execute",
                    Attributes = MemberAttributes.Public | MemberAttributes.Final
                };

                // Add new method to the class
                fooBarCodeTypeDecl.Members.Add(executeCodeMember);

                // Decorate method with TestMethod attribute
                executeCodeMember.CustomAttributes.Add(
                    new CodeAttributeDeclaration("TestMethod"));

                // Create DataSource attribute. Output the constructor that takes 4 parameters of which three are strings and te last one is an enum.
                var dataSourceCodeAttrDecl = new CodeAttributeDeclaration("DataSource",
                    new CodeAttributeArgument(new CodePrimitiveExpression("Microsoft.VisualStudio.TestTools.DataSource.TestCase")),
                    new CodeAttributeArgument(new CodePrimitiveExpression(string.Format("http://tfsserver:8080/tfs/troolean;{0}", "Product1"))),
                    new CodeAttributeArgument(new CodePrimitiveExpression("100")));

                // The last parameter is an enum
                CodeTypeReferenceExpression dataAccessMethodCodeTypeRefExpr = new CodeTypeReferenceExpression("DataAccessMethod");
                dataSourceCodeAttrDecl.Arguments.Add(new CodeAttributeArgument(new CodeFieldReferenceExpression(dataAccessMethodCodeTypeRefExpr, "Sequential")));

                //  Decorate the method with the DataSource attribute
                executeCodeMember.CustomAttributes.Add(dataSourceCodeAttrDecl);

                /*
                namespace Troolean.CodeDom.Demo
                {
                    using Microsoft.VisualStudio.TestTools.UnitTesting;
                    using System;

                    [TestClass()]
                    public partial class FooBar
                    {

                        [TestMethod()]
                        [DataSource("Microsoft.VisualStudio.TestTools.DataSource.TestCase", "http://tfsserver:8080/tfs/troolean;Product1", "100", DataAccessMethod.Sequential)]
                        public void Execute()
                        {
                        }
                    }
                }
                */

                // Generate the code and output to console
                codeProvider.GenerateCodeFromNamespace(
                    demoCodeNamespace,
                    Console.Out,
                    new CodeGeneratorOptions
                    {
                        BlankLinesBetweenMembers = true,
                        BracingStyle = "C"
                    }
                );
            }
        }
    }
}