internal static Func <IDataRecord, object> CreateFactory( DbClassInfoCache target, FactoryHelperSettings settings) { var generator = ClassInfoGenerator.SuperClass(target); generator.Namespace = target.Type.Namespace; if (target.Constructors.Any(f => f.Arguments.Any())) { throw new TypeAccessException( string.Format("Target type '{0}' does not define an public not " + "parameterizable constructor. POCO's!!!!", target.Name)); } var cp = new CompilerParameters(); cp.GenerateInMemory = true; //if (settings.FileCollisonDetection == CollisonDetectionMode.Pessimistic) //{ // cp.OutputAssembly = // Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) // + @"\" // + Guid.NewGuid().ToString("N") // + "_Poco.dll"; //} //else //{ // cp.OutputAssembly = // Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) // + @"\" + target.Type.FullName // + "_Poco.dll"; //} //settings.TempFileData.Add(cp.OutputAssembly); ConstructorInfo[] constructorInfos = null; TypeInfo targetType = null; //if (File.Exists(cp.OutputAssembly) && settings.FileCollisonDetection == CollisonDetectionMode.Optimistic) //{ // var bufferAssam = Assembly.Load(cp.OutputAssembly); // targetType = target.Type.GetTypeInfo(); // var type = bufferAssam.DefinedTypes.FirstOrDefault(s => s == targetType); // if (targetType != null) // { // constructorInfos = targetType.GetConstructors(); // } // if (constructorInfos == null) // { // throw new Exception( // string.Format( // "A dll with a matching name for type: {0} was found and the FileCollisonDetection is Optimistic but no matching Constuctors where found", // type.Name)); // } //} if (constructorInfos == null) { var callingAssm = Assembly.GetEntryAssembly(); if (callingAssm == null) { callingAssm = Assembly.GetExecutingAssembly(); } if (settings.CreateDebugCode) { cp.TempFiles = new TempFileCollection(Path.GetDirectoryName(callingAssm.Location), true); cp.GenerateInMemory = false; cp.TempFiles.KeepFiles = true; cp.IncludeDebugInformation = true; } //cp.GenerateExecutable = true; cp.ReferencedAssemblies.Add(target.Type.Assembly.Location); cp.ReferencedAssemblies.Add("System.dll"); cp.ReferencedAssemblies.Add("System.Core.dll"); cp.ReferencedAssemblies.Add("System.Data.dll"); cp.ReferencedAssemblies.Add("System.Xml.dll"); cp.ReferencedAssemblies.Add("System.Xml.Linq.dll"); cp.ReferencedAssemblies.Add(typeof(DbAccessLayer).Assembly.Location); foreach (var defaultNamespace in settings.DefaultNamespaces) { generator.NamespaceImports.Add(defaultNamespace); } foreach ( var additionalNamespace in target.Attributes.Where(f => f.Attribute is AutoGenerateCtorNamespaceAttribute) .Select(f => f.Attribute as AutoGenerateCtorNamespaceAttribute)) { generator.NamespaceImports.Add(additionalNamespace.UsedNamespace); } var provider = new CSharpCodeProvider(); var compileAssemblyFromDom = provider.CompileAssemblyFromSource(cp, generator.RenderPocoClass()); if (compileAssemblyFromDom.Errors.Count > 0 && !settings.EnforceCreation) { var sb = new StringBuilder(string.Format("There are {0} errors due compilation.", compileAssemblyFromDom.Errors.Count)); var errNr = 0; foreach (CompilerError error in compileAssemblyFromDom.Errors) { sb.AppendLine(errNr++ + error.ErrorNumber + ":" + error.Column + "," + error.Line + " -> " + error.ErrorText); } var ex = new InvalidDataException(sb.ToString()); ex.Data.Add("Object", compileAssemblyFromDom); throw ex; } var compiledAssembly = compileAssemblyFromDom.CompiledAssembly; targetType = compiledAssembly.DefinedTypes.First(); constructorInfos = targetType.GetConstructors(); if (!constructorInfos.Any()) { if (settings.EnforceCreation) { return(null); } var ex = new InvalidDataException("There are was an unknown error due compilation. No CTOR was build"); ex.Data.Add("Object", compileAssemblyFromDom); foreach (CompilerError error in compileAssemblyFromDom.Errors) { ex.Data.Add(error.ErrorNumber, error); } throw ex; } } var matchingCtor = constructorInfos.FirstOrDefault(s => { var param = s.GetParameters(); if (param.Length < 1) { return(false); } if (param.First().ParameterType != typeof(EagarDataRecord)) { return(false); } return(true); }); var dm = new DynamicMethod("Create" + target.Name.Split('.')[0], target.Type, new[] { typeof(IDataRecord) }, target.Type, true); var il = dm.GetILGenerator(); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Newobj, matchingCtor ?? throw new InvalidOperationException()); il.Emit(OpCodes.Ret); if (!settings.CreateDebugCode) { foreach (string tempFile in cp.TempFiles) { if (!tempFile.EndsWith("dll") && !tempFile.EndsWith("pdb")) { File.Delete(tempFile); } } } var func = (Func <IDataRecord, object>)dm.CreateDelegate(typeof(Func <IDataRecord, object>)); return(func); }
internal static Func <IDataRecord, object> CreateFactory( DbClassInfoCache target, FactoryHelperSettings settings) { var generator = ClassInfoGenerator.SuperClass(target); generator.Namespace = target.Type.Namespace; if (target.Constructors.Any(f => f.Arguments.Any())) { throw new TypeAccessException( string.Format("Target type '{0}' does not define an public not " + "parameterizable constructor. POCO's!!!!", target.Name)); } //var cp = new CompilerParameters(); //cp.GenerateInMemory = true; //var callingAssm = Assembly.GetEntryAssembly(); //if (callingAssm == null) //{ // callingAssm = Assembly.GetExecutingAssembly(); //} //if (settings.CreateDebugCode) //{ // cp.TempFiles = new TempFileCollection(Path.GetDirectoryName(callingAssm.Location), true); // cp.GenerateInMemory = false; // cp.TempFiles.KeepFiles = true; // cp.IncludeDebugInformation = true; //} var references = new List <string>(); references.Add(target.Type.Assembly.Location); #if NETFULL references.Add("System.dll"); references.Add("System.Core.dll"); references.Add("System.Data.dll"); references.Add("System.Xml.dll"); references.Add("System.Xml.Linq.dll"); #elif NETCORE #endif references.Add(typeof(DbAccessLayer).Assembly.Location); foreach (var defaultNamespace in settings.DefaultNamespaces) { generator.NamespaceImports.Add(defaultNamespace); } foreach ( var additionalNamespace in target.Attributes.Where(f => f.Attribute is AutoGenerateCtorNamespaceAttribute) .Select(f => f.Attribute as AutoGenerateCtorNamespaceAttribute)) { generator.NamespaceImports.Add(additionalNamespace.UsedNamespace); } var syntaxTree = CSharpSyntaxTree.ParseText(generator.RenderPocoClass(), new CSharpParseOptions(LanguageVersion.Latest, DocumentationMode.None, SourceCodeKind.Regular)); using (var assemblyStream = new MemoryStream()) { EmitResult compileAssemblyFromDom; try { var cSharpCompilation = CSharpCompilation.Create(target.Type.FullName + "_Poco.dll", new[] { syntaxTree }, _defaultReferences.Concat(new MetadataReference[] { MetadataReference.CreateFromFile(target.Type.Assembly.Location), }), new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)); cSharpCompilation = cSharpCompilation.AddReferences(); compileAssemblyFromDom = cSharpCompilation .Emit(assemblyStream); } catch (Exception e) { Console.WriteLine(e); throw; } finally { } if (!compileAssemblyFromDom.Success) { var sb = new StringBuilder(string.Format("There are {0} errors due compilation.", compileAssemblyFromDom.Diagnostics.Length)); var errNr = 0; foreach (var error in compileAssemblyFromDom.Diagnostics) { sb.AppendLine(errNr++ + error.Id + ":" + error.Location.GetLineSpan() + " -> " + error.GetMessage()); } var ex = new InvalidDataException(sb.ToString()); ex.Data.Add("Object", compileAssemblyFromDom); throw ex; } var compiledAssembly = Assembly.Load(assemblyStream.ToArray()); var targetType = compiledAssembly.DefinedTypes.First(); var constructorInfos = targetType.GetConstructors(); if (!constructorInfos.Any()) { if (settings.EnforceCreation) { return(null); } var ex = new InvalidDataException("There are was an unknown error due compilation. No CTOR was build"); ex.Data.Add("Object", compileAssemblyFromDom); for (var index = 0; index < compileAssemblyFromDom.Diagnostics.Length; index++) { var error = compileAssemblyFromDom.Diagnostics[index]; ex.Data.Add(index, error); } throw ex; } var matchingCtor = constructorInfos.FirstOrDefault(s => { var param = s.GetParameters(); if (param.Length < 1) { return(false); } if (param.First().ParameterType != typeof(EagarDataRecord)) { return(false); } return(true); }); matchingCtor = matchingCtor ?? throw new InvalidOperationException( $"Could not find a matching constructor \".ctor(EagarDataRecord record)\" on \"{targetType}\""); return((record) => matchingCtor.Invoke(new object[] { record })); //var dm = new DynamicMethod("Create" + target.Name.Split('.')[0], target.Type, new[] { typeof(IDataRecord) }, // target.Type, true); //var il = dm.GetILGenerator(); //il.Emit(OpCodes.Ldarg_0); //il.Emit(OpCodes.Newobj, matchingCtor ?? throw new InvalidOperationException()); //il.Emit(OpCodes.Ret); //if (!settings.CreateDebugCode) //{ // foreach (string tempFile in cp.TempFiles) // { // if (!tempFile.EndsWith("dll") && !tempFile.EndsWith("pdb")) // { // File.Delete(tempFile); // } // } //} //var func = (Func<IDataRecord, object>)dm.CreateDelegate(typeof(Func<IDataRecord, object>)); //return func; } }