private CompilerResults BuildAssembly(GatewayLoader gatewayLoader, string code, AssemblyName name, string ns) { var sb = new StringBuilder(); sb.AppendLine("using System;"); sb.AppendLine("using System.Collections.Generic;"); sb.AppendLine("using System.Collections;"); sb.AppendLine("using System.Linq;"); sb.AppendLine("using UmbracoLinqPad;"); sb.AppendLine("using UmbracoLinqPad.Proxies;"); sb.AppendLine("using System.IO;"); sb.AppendLine("using System.Reflection;"); sb.AppendLine("using UmbracoLinqPad.Gateway;"); sb.Append("namespace "); sb.Append(ns); sb.AppendLine(" {"); //open ns sb.AppendLine(code); sb.Append("}"); //end ns // Use the CSharpCodeProvider to compile the generated code: CompilerResults results; using (var codeProvider = new CSharpCodeProvider(new Dictionary <string, string>() { { "CompilerVersion", "v4.0" } })) { var options = new CompilerParameters( "System.dll System.Core.dll System.Xml.dll".Split(), name.CodeBase, true); //add this assembly reference (UmbracoLinqPad) options.ReferencedAssemblies.Add(typeof(UmbracoDynamicDriver).Assembly.Location); //add the UmbracoLinqPad.Gateway assembly reference options.ReferencedAssemblies.Add(gatewayLoader.GatewayAssembly.Location); //add the IQToolkit assembly reference options.ReferencedAssemblies.Add(gatewayLoader.IqToolkitAssembly.Location); //add the Umbraco.Core assembly reference options.ReferencedAssemblies.Add(gatewayLoader.UmbracoCoreAssembly.Location); results = codeProvider.CompileAssemblyFromSource(options, sb.ToString()); } if (results.Errors.Count > 0) { throw new Exception ("Cannot compile typed context: " + results.Errors[0].ErrorText + " (line " + results.Errors[0].Line + ")" + "\r\n\r\n" + sb.ToString()); } return(results); }
public override List <ExplorerItem> GetSchemaAndBuildAssembly(IConnectionInfo cxInfo, AssemblyName assemblyToBuild, ref string nameSpace, ref string typeName) { nameSpace = "Umbraco.Generated"; typeName = "GeneratedUmbracoDataContext"; var umbFolder = new DirectoryInfo(cxInfo.AppConfigPath); //load all assemblies in the umbraco bin folder var loadedAssemblies = Directory.GetFiles(Path.Combine(umbFolder.FullName, "bin"), "*.dll").Select(LoadAssemblySafely).ToList(); //we'll need to manually resolve any assemblies loaded above AppDomain.CurrentDomain.AssemblyResolve += (sender, args) => { //This is stupid but is required becaue the TypeFinder is looking for an App_Code assembly, so we'll generate an empty one if (args.Name == "App_Code") { return(ResolveAppCode()); } var found = loadedAssemblies.FirstOrDefault(x => x.GetName().Name == new AssemblyName(args.Name).Name); return(found); }; //Create a loader to startup the umbraco app to create the schema and the generated DataContext class var driverFolder = GetDriverFolder(); var gatewayLoader = new GatewayLoader( LoadAssemblySafely(Path.Combine(driverFolder, "UmbracoLinqPad.Gateway.dll")), loadedAssemblies.Single(x => x.GetName().Name == "Umbraco.Core"), LoadAssemblySafely(Path.Combine(driverFolder, "IQToolkit.dll"))); using (var app = gatewayLoader.StartUmbracoApplication(new DirectoryInfo(cxInfo.AppConfigPath))) { using (var appCtx = app.ApplicationContext) { var contentItemsCompiler = (IContentItemsCompiler)Activator.CreateInstance( gatewayLoader.GatewayAssembly.GetType("UmbracoLinqPad.Gateway.Compilers.ContentItemsCompiler")); var dataContextCompiler = (IDataContextCompiler)Activator.CreateInstance( gatewayLoader.GatewayAssembly.GetType("UmbracoLinqPad.Gateway.Compilers.DataContextCompiler")); var sb = new StringBuilder(); //create the content type classes foreach (var compiled in contentItemsCompiler.GenerateClasses(appCtx.RealUmbracoApplicationContext)) { sb.Append(compiled); } //add the data context class sb.Append(dataContextCompiler.GenerateClass(typeName, appCtx.RealUmbracoApplicationContext)); var result = BuildAssembly(gatewayLoader, sb.ToString(), assemblyToBuild, nameSpace); var dataContextType = result.CompiledAssembly.GetType(string.Format("{0}.{1}", nameSpace, typeName)); var properties = dataContextType.GetProperties() //Get all properties of enumerable IGeneratedContentBase .Where(x => typeof(IEnumerable <Models.IGeneratedContentBase>).IsAssignableFrom(x.PropertyType)) .GroupBy(x => x.Name.Split('_')[0]); //group on 'category' property name return(properties.Select(category => new ExplorerItem(category.Key, ExplorerItemKind.Category, ExplorerIcon.Table) { Children = category .Select(x => new ExplorerItem(x.Name, ExplorerItemKind.QueryableObject, ExplorerIcon.View) { IsEnumerable = true }).ToList() }).ToList()); } } }