using Microsoft.CSharp; using Microsoft.ML; using Microsoft.ML.Data; using System; using System.CodeDom.Compiler; using System.Collections; using System.Collections.Generic; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Text; using System.Text.RegularExpressions; using System.Threading.Tasks; namespace testML { public static class DictionaryToObjectConverter { public static IEnumerable Convert(List> data, string toPredict, string objectFilename, out Type classType, out Type classPredictionType, out DataViewSchema schema) { var regexCR = new Regex(@"_CR\d+"); var currentCR = regexCR.Match(toPredict ?? string.Empty).Groups[0].Value; var schemaBuilder = new DataViewSchema.Builder(); var definition = new Dictionary(); var sample = data.FirstOrDefault(); if (sample != null) { foreach (var key in sample.Keys) { if (currentCR != null && !key.Contains(currentCR)) { continue; } //Buscamos el tipo var sampleValue = (from x in data where x.ContainsKey(key) && x[key] != null select x[key]).FirstOrDefault(); if (sampleValue != null) { var keyType = sampleValue.GetType(); definition.Add(key, keyType); if (keyType == typeof(string)) { schemaBuilder.AddColumn(key, TextDataViewType.Instance); } else if (keyType == typeof(double)) { schemaBuilder.AddColumn(key, NumberDataViewType.Double); } else if (keyType == typeof(float)) { schemaBuilder.AddColumn(key, NumberDataViewType.Single); } else if (keyType == typeof(int)) { schemaBuilder.AddColumn(key, NumberDataViewType.Int32); } else if (keyType == typeof(long)) { schemaBuilder.AddColumn(key, NumberDataViewType.Int64); } } } } var className = "OBJ" + Path.GetFileNameWithoutExtension(objectFilename).Replace(".", "_"); Assembly dllAssembly = null; if (File.Exists(Path.Combine(Environment.CurrentDirectory, objectFilename))) { dllAssembly = Assembly.LoadFrom(Path.Combine(Environment.CurrentDirectory, objectFilename)); } else { var converter = new DictionaryToObjectConverterClass() { ClassName = className, ToPredict = toPredict ?? "Empty", Definition = definition }; var classCode = converter.TransformText(); File.WriteAllText(Path.Combine(Environment.CurrentDirectory, objectFilename + ".cs"), classCode, Encoding.UTF8); string exDir = System.Runtime.InteropServices.RuntimeEnvironment.GetRuntimeDirectory().Trim(Path.DirectorySeparatorChar); CompilerParameters compilerParameters = new CompilerParameters { GenerateExecutable = false, GenerateInMemory = false, IncludeDebugInformation = true, TreatWarningsAsErrors = false, OutputAssembly = Path.Combine(Environment.CurrentDirectory, objectFilename), CompilerOptions = string.Format("/target:library /lib:{0}", exDir) }; var mlDir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); foreach (var item in AppDomain.CurrentDomain.GetAssemblies()) { compilerParameters.ReferencedAssemblies.Add(item.Location); } // compilerParameters.ReferencedAssemblies.Add(Assembly.GetExecutingAssembly().Location); CompilerResults compilerResults = new CSharpCodeProvider(new Dictionary { { "CompilerVersion", "v4.0" } }).CompileAssemblyFromSource(compilerParameters, new string[] { classCode } ); dllAssembly = compilerResults.CompiledAssembly; } classType = dllAssembly.GetType("DictionaryToObjectConverterNamespace." + className); classPredictionType = dllAssembly.GetType("DictionaryToObjectConverterNamespace." + className + "Prediction"); Type listType = typeof(List<>); Type genericType = listType.MakeGenericType(classType); var result = (IList)Activator.CreateInstance(genericType); foreach (var inputData in data) { var outputData = (IDictionaryToObjectConverter)Activator.CreateInstance(classType); result.Add(outputData); foreach (var key in inputData.Keys) { outputData[key] = inputData[key]; } } schema = schemaBuilder.ToSchema(); return (IEnumerable)result; } } public partial class DictionaryToObjectConverterClass { public string ClassName { get; set; } public string ToPredict { get; set; } public Dictionary Definition { get; set; } } public interface IDictionaryToObjectConverter { object this[string propertyName] { get; set; } void SetValue(string propertyName, object value); object GetValue(string propertyName); } }