Skip to content

Instantly share code, notes, and snippets.

@drmohundro
Created February 19, 2021 01:27
Show Gist options
  • Save drmohundro/a2e511bc28f2af55ac4cb56d5a3beafd to your computer and use it in GitHub Desktop.
Save drmohundro/a2e511bc28f2af55ac4cb56d5a3beafd to your computer and use it in GitHub Desktop.
FluentTypeGenerator - Old POC I did for a fluent type generator class
using System;
using System.CodeDom;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.IO;
using System.Web;
using Omitted.Utilities.SystemTypeExtensions;
namespace Omitted.Services.Forms.Core.Clients.Generation
{
public class FluentTypeGeneratorTest
{
public void TestSyntax()
{
var builder = new FluentTypeGenerator<FormBase>("AwesomeAssembly", "MyAwesomeType");
builder.AddGacReferences(new[] {
"System",
"System.Core",
"mscorlib"
});
builder.AddBinReferences(new[] {
"System.ComponentModel.DataAnnotations",
"Omitted.Public.Library",
"Omitted",
"Omitted.Services.Forms.Core"
});
builder.ImportNamespaces(new[] {
"System",
"System.ComponentModel.DataAnnotations",
"System.ComponentModel",
"Omitted.Public.Library.Forms",
"System.Collections.Generic",
"System.Linq",
"Omitted.Services.Forms.Core"
});
builder.AddProperty(x =>
x.TypeAndName("bool", "IsRequired")
.Attribute("UIHint", "this is my name")
.Get(() => "return true;"));
var form = builder.Build();
}
}
public class FluentTypeGenerator<TBaseType>
{
private readonly CompilerParameters _parms;
private readonly CodeCompileUnit _compileUnit;
private readonly CodeTypeDeclaration _classDeclaration;
public FluentTypeGenerator(string assemblyName, string typeName)
{
_parms = new CompilerParameters();
_compileUnit = new CodeCompileUnit();
_classDeclaration = new CodeTypeDeclaration(typeName);
_parms.GenerateExecutable = false;
_parms.GenerateInMemory = true;
_parms.OutputAssembly = GetAssemblyLocation(assemblyName);
_parms.IncludeDebugInformation = false;
_parms.TempFiles.KeepFiles = true;
}
public void AddGacReferences(string[] gacDeployedReferences)
{
gacDeployedReferences.ForEach(asm => _parms.ReferencedAssemblies.Add(asm + ".dll"));
}
public void AddBinReferences(string[] binDeployedReferences)
{
binDeployedReferences.ForEach(asm =>
{
var strPath = Path.Combine(HttpContext.Current.Server.MapPath("/bin"), asm + ".dll");
_parms.ReferencedAssemblies.Add(strPath);
});
}
public void ImportNamespaces(string[] importedNamespaces)
{
var codeNamespace = new CodeNamespace(typeof(TBaseType).Namespace);
importedNamespaces.ForEach(n => codeNamespace.Imports.Add(new CodeNamespaceImport(n)));
codeNamespace.Types.Add(_classDeclaration);
_compileUnit.Namespaces.Add(codeNamespace);
}
public void AddProperty(Action<PropertyBuilder> propertyBuilder)
{
var fluentProperty = new PropertyBuilder();
propertyBuilder(fluentProperty);
}
public TBaseType Build()
{
CodeDomProvider provider = new Microsoft.CSharp.CSharpCodeProvider(new Dictionary<string, string> { { "CompilerVersion", "v3.5" } });
var results = provider.CompileAssemblyFromDom(_parms, _compileUnit);
}
private static string GetAssemblyLocation(string assemblyName)
{
return @"C:\Windows\Temp\" + assemblyName;
}
}
public class PropertyBuilder
{
private string _type;
private string _name;
internal PropertyBuilder()
{
}
public PropertyBuilder TypeAndName(string type, string name)
{
_type = type;
_name = name;
return this;
}
public PropertyBuilder Attribute(string attributeType, string attributeSnippet)
{
return this;
}
public PropertyBuilder Get(Func<string> getterSnippet)
{
return this;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment