示例#1
0
        /// <summary>
        ///     Generates a Constructor with a Full Ado.Net constructor
        /// </summary>
        /// <param name="target"></param>
        /// <param name="settings"></param>
        /// <param name="importNameSpace"></param>
        /// <returns></returns>
        public static CodeMemberMethod GenerateConstructor(DbClassInfoCache target, FactoryHelperSettings settings,
                                                           CodeNamespace importNameSpace)
        {
            var codeConstructor = GenerateTypeConstructor();

            GenerateBody(target, settings, importNameSpace, codeConstructor, new CodeBaseReferenceExpression());
            return(codeConstructor);
        }
示例#2
0
 /// <summary>
 ///     Generates a C# DOM body for an IDataReader loader.
 /// </summary>
 /// <param name="sourceType">Type of the source.</param>
 /// <param name="settings">The settings.</param>
 /// <param name="importNameSpace">The import name space.</param>
 /// <param name="container">The container.</param>
 /// <param name="target">The target.</param>
 public static void GenerateBody(DbClassInfoCache sourceType,
                                 FactoryHelperSettings settings,
                                 CodeNamespace importNameSpace,
                                 CodeMemberMethod container,
                                 CodeExpression target)
 {
     GenerateBody(sourceType.Propertys, settings, importNameSpace, container, target);
 }
示例#3
0
		/// <summary>
		/// Generates a Function with a Full ado.net constructor beavior.
		/// It Creates a new Instance of <param name="target"></param> and then fills all public properties
		/// </summary>
		/// <param name="target"></param>
		/// <param name="settings"></param>
		/// <param name="importNameSpace"></param>
		/// <returns></returns>
		public static CodeMemberMethod GenerateFactory(DbClassInfoCache target, FactoryHelperSettings settings, CodeNamespace importNameSpace)
		{
			var codeFactory = GenerateTypeConstructor(true);
			var super = new CodeVariableReferenceExpression("super");

			var pocoVariable = new CodeVariableDeclarationStatement(target.Type, "super");
			codeFactory.Statements.Add(pocoVariable);

			var codeAssignment = new CodeAssignStatement(super, new CodeObjectCreateExpression(target.Type));
			codeFactory.Statements.Add(codeAssignment);

			GenerateBody(target, settings, importNameSpace, codeFactory, super);
			codeFactory.ReturnType = new CodeTypeReference(target.Type);
			codeFactory.Statements.Add(new CodeMethodReturnStatement(super));

			return codeFactory;
		}
示例#4
0
        /// <summary>
        ///     Generates a Function with a Full ado.net constructor beavior.
        ///     It Creates a new Instance of
        ///     <paramref name="target"></paramref>
        ///     and then fills all public properties
        /// </summary>
        /// <param name="target"></param>
        /// <param name="settings"></param>
        /// <param name="importNameSpace"></param>
        /// <returns></returns>
        public static CodeMemberMethod GenerateFactory(DbClassInfoCache target, FactoryHelperSettings settings,
                                                       CodeNamespace importNameSpace)
        {
            var codeFactory = GenerateTypeConstructor(true);
            var super       = new CodeVariableReferenceExpression("super");

            var pocoVariable = new CodeVariableDeclarationStatement(target.Type, "super");

            codeFactory.Statements.Add(pocoVariable);

            var codeAssignment = new CodeAssignStatement(super, new CodeObjectCreateExpression(target.Type));

            codeFactory.Statements.Add(codeAssignment);

            GenerateBody(target, settings, importNameSpace, codeFactory, super);
            codeFactory.ReturnType = new CodeTypeReference(target.Type);
            codeFactory.Statements.Add(new CodeMethodReturnStatement(super));

            return(codeFactory);
        }
示例#5
0
		/// <summary>
		/// Generates a Constructor with a Full Ado.Net constructor
		/// </summary>
		/// <param name="target"></param>
		/// <param name="settings"></param>
		/// <param name="importNameSpace"></param>
		/// <returns></returns>
		public static CodeMemberMethod GenerateConstructor(DbClassInfoCache target, FactoryHelperSettings settings, CodeNamespace importNameSpace)
		{
			var codeConstructor = GenerateTypeConstructor();
			GenerateBody(target, settings, importNameSpace, codeConstructor, new CodeBaseReferenceExpression());
			return codeConstructor;
		}
示例#6
0
		internal static Func<IDataRecord, object> CreateFactory(DbClassInfoCache target, FactoryHelperSettings settings)
		{
			var classCtorAttr =
				target.Attributes.First(s => s.Attribute is AutoGenerateCtorAttribute).Attribute as
					AutoGenerateCtorAttribute;

			CodeNamespace importNameSpace;
			importNameSpace = new CodeNamespace(target.Type.Namespace);
			var cp = new CompilerParameters();
			string superName;
			var compiler = new CodeTypeDeclaration();
			compiler.IsClass = true;

			var generateFactory = target.Type.IsSealed || classCtorAttr.CtorGeneratorMode == CtorGeneratorMode.FactoryMethod;

			CodeMemberMethod codeConstructor;
			var codeName = target.Name.Split('.').Last();

			if (generateFactory)
			{
				codeConstructor = GenerateFactory(target, settings, importNameSpace);
				superName = codeName + "_Factory";
				compiler.Attributes = MemberAttributes.Static;
			}
			else
			{
				compiler.BaseTypes.Add(target.Type);
				codeConstructor = GenerateConstructor(target, settings, importNameSpace);
				compiler.IsPartial = true;
				superName = codeName + "_Super";
			}
			if (target.Constructors.Any(f => f.Arguments.Any()))
			{
				throw new TypeAccessException(string.Format("Target type '{0}' does not define an public parametherless constructor. POCO's!!!!", target.Name));
			}

			compiler.Attributes |= MemberAttributes.Public;
			compiler.Name = superName;
			compiler.Members.Add(codeConstructor);

			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);

			Assembly compiledAssembly;
			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)
				{
					//testing we are?
					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);
				var compileUnit = new CodeCompileUnit();

				foreach (var defaultNamespace in settings.DefaultNamespaces)
				{
					importNameSpace.Imports.Add(new CodeNamespaceImport(defaultNamespace));
				}

				foreach (var additionalNamespace in target.Attributes.Where(f => f.Attribute is AutoGenerateCtorNamespaceAttribute).Select(f => f.Attribute as AutoGenerateCtorNamespaceAttribute))
				{
					importNameSpace.Imports.Add(new CodeNamespaceImport(additionalNamespace.UsedNamespace));
				}

				if (classCtorAttr.FullSateliteImport)
				{
					foreach (var referencedAssembly in target.Type.Assembly.GetReferencedAssemblies())
					{
						cp.ReferencedAssemblies.Add(referencedAssembly.Name);
					}
				}

				importNameSpace.Types.Add(compiler);

				compileUnit.Namespaces.Add(importNameSpace);
				var provider = new CSharpCodeProvider();
				var compileAssemblyFromDom = provider.CompileAssemblyFromDom(cp, compileUnit);

				if (compileAssemblyFromDom.Errors.Count > 0 && !settings.EnforceCreation)
				{
					var sb = new StringBuilder(string.Format("There are {0} errors due compilation.",
							compileAssemblyFromDom.Errors.Count));
					int 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;
				}

				compiledAssembly = compileAssemblyFromDom.CompiledAssembly;

				targetType = compiledAssembly.DefinedTypes.First();
				constructorInfos = targetType.GetConstructors();
				if (!constructorInfos.Any())
				{
					if (settings.EnforceCreation)
						return null;
					var ex =
						new InvalidDataException(string.Format("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 (generateFactory)
				{
					if (param.Length < 1)
						return false;
					if (param.First().ParameterType != typeof(IDataRecord))
						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();
			if (generateFactory)
			{
				il.Emit(OpCodes.Nop);
				il.Emit(OpCodes.Ldarg_0);
				il.Emit(OpCodes.Call, targetType.GetMethod("Factory"));
				il.Emit(OpCodes.Ret);
			}
			else
			{
				il.Emit(OpCodes.Ldarg_0);
				il.Emit(OpCodes.Newobj, matchingCtor);
				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;
		}
示例#7
0
		public static void GenerateBody(DbClassInfoCache sourceType,
			FactoryHelperSettings settings,
			CodeNamespace importNameSpace,
			CodeMemberMethod container,
			CodeExpression target)
		{
			GenerateBody(sourceType.Propertys, settings, importNameSpace, container, target);
		}
示例#8
0
		/// <summary>
		/// Creates a new body in stlye of an Ado.net Constructor and attaches it to the <paramref name="target"/>
		/// </summary>
		/// <param name="properties"></param>
		/// <param name="settings"></param>
		/// <param name="importNameSpace"></param>
		/// <param name="container"></param>
		/// <param name="target"></param>
		public static void GenerateBody(Dictionary<string, DbPropertyInfoCache> properties,
			FactoryHelperSettings settings,
			CodeNamespace importNameSpace,
			CodeMemberMethod container,
			CodeExpression target)
		{
			foreach (var propertyInfoCache in properties.Values)
			{
				propertyInfoCache.Refresh();

				var columnName = propertyInfoCache.DbName;

				if (settings.EnforcePublicPropertys)
				{
					if (propertyInfoCache.Getter.MethodInfo.IsPrivate)
						throw new AccessViolationException(string.Format(
							"The Getter of {0} is private. Full creation cannot be enforced", propertyInfoCache.PropertyName));
					if (propertyInfoCache.Setter.MethodInfo.IsPrivate)
						throw new AccessViolationException(string.Format(
							"The Setter of {0} is private. Full creation cannot be enforced", propertyInfoCache.PropertyName));
				}

				var codeIndexerExpression = new CodeIndexerExpression(new CodeVariableReferenceExpression("record"),
					new CodePrimitiveExpression(columnName));

				var variableName = columnName.ToLower();
				CodeVariableDeclarationStatement bufferVariable = null;

				//var propertyRef = new CodeVariableReferenceExpression(propertyInfoCache.PropertyName);

				var refToProperty = new CodeFieldReferenceExpression(target, propertyInfoCache.PropertyName);

				var attributes = propertyInfoCache.Attributes;
				var valueConverterAttributeModel =
					attributes.FirstOrDefault(s => s.Attribute is ValueConverterAttribute);
				var isXmlProperty = attributes.FirstOrDefault(s => s.Attribute is FromXmlAttribute);
				CodeVariableReferenceExpression uncastLocalVariableRef = null;

				if (isXmlProperty != null)
				{
					bufferVariable = new CodeVariableDeclarationStatement(typeof(object), variableName);
					container.Statements.Add(bufferVariable);
					uncastLocalVariableRef = new CodeVariableReferenceExpression(variableName);
					var buffAssignment = new CodeAssignStatement(uncastLocalVariableRef, codeIndexerExpression);
					container.Statements.Add(buffAssignment);

					var checkXmlForNull = new CodeConditionStatement();
					checkXmlForNull.Condition = new CodeBinaryOperatorExpression(
						new CodeVariableReferenceExpression(variableName),
						CodeBinaryOperatorType.IdentityInequality,
						new CodeFieldReferenceExpression(new CodeVariableReferenceExpression("System.DBNull"), "Value"));
					container.Statements.Add(checkXmlForNull);

					var xmlRecordType = new CodeTypeReferenceExpression(typeof(XmlDataRecord));
					importNameSpace.Imports.Add(new CodeNamespaceImport(typeof(DbClassInfoCache).Namespace));
					importNameSpace.Imports.Add(new CodeNamespaceImport(typeof(DataConverterExtensions).Namespace));
					importNameSpace.Imports.Add(new CodeNamespaceImport(typeof(DbConfigHelper).Namespace));

					if (propertyInfoCache.CheckForListInterface())
					{
						var typeArgument = propertyInfoCache.PropertyInfo.PropertyType.GetGenericArguments().FirstOrDefault();
						var codeTypeOfListArg = new CodeTypeOfExpression(typeArgument);

						var instanceHelper = new CodeMethodInvokeExpression(
							new CodeTypeReferenceExpression(typeof(NonObservableDbCollection<>).MakeGenericType(typeArgument)),
							"FromXml",
							new CodeCastExpression(typeof(string), new CodeVariableReferenceExpression(variableName)));

						//var tryParse = new CodeMethodInvokeExpression(xmlRecordType,
						//	"TryParse",
						//	new CodeCastExpression(typeof(string), uncastLocalVariableRef),
						//	codeTypeOfListArg,
						//	new CodePrimitiveExpression(false));

						//var xmlDataRecords = new CodeMethodInvokeExpression(tryParse, "CreateListOfItems");
						//var getClassInfo = new CodeMethodInvokeExpression(codeTypeOfListArg, "GetClassInfo");

						//var xmlRecordsToObjects = new CodeMethodInvokeExpression(xmlDataRecords, "Select",
						//	new CodeMethodReferenceExpression(getClassInfo, "SetPropertysViaReflection"));

						//CodeObjectCreateExpression collectionCreate;
						//if (typeArgument != null && (typeArgument.IsClass && typeArgument.GetInterface("INotifyPropertyChanged") != null))
						//{
						//	collectionCreate = new CodeObjectCreateExpression(typeof(DbCollection<>).MakeGenericType(typeArgument),
						//		xmlRecordsToObjects);
						//}
						//else
						//{
						//	collectionCreate = new CodeObjectCreateExpression(typeof(NonObservableDbCollection<>).MakeGenericType(typeArgument),
						//		xmlRecordsToObjects);
						//}

						var setExpr = new CodeAssignStatement(refToProperty, instanceHelper);
						checkXmlForNull.TrueStatements.Add(setExpr);
					}
					else
					{
						var typeofProperty = new CodeTypeOfExpression(propertyInfoCache.PropertyType);
						var getClassInfo = new CodeMethodInvokeExpression(typeofProperty, "GetClassInfo");

						var tryParse = new CodeMethodInvokeExpression(xmlRecordType,
							"TryParse",
							new CodeCastExpression(typeof(string), uncastLocalVariableRef),
							typeofProperty,
							new CodePrimitiveExpression(true));

						var setProps = new CodeMethodInvokeExpression(getClassInfo, "SetPropertysViaReflection", tryParse,
							new CodeSnippetExpression("null"),
							new CodeSnippetExpression("null"));
						var setExpr = new CodeAssignStatement(refToProperty,
							new CodeCastExpression(propertyInfoCache.PropertyType, setProps));
						checkXmlForNull.TrueStatements.Add(setExpr);
					}
				}
				else
				{
					//Should the SQL value be converted
					if (valueConverterAttributeModel != null)
					{
						//create object buff123;
						bufferVariable = new CodeVariableDeclarationStatement(typeof(object), variableName);
						container.Statements.Add(bufferVariable);
						//Assing buff123 = record[x]
						uncastLocalVariableRef = new CodeVariableReferenceExpression(variableName);
						var buffAssignment = new CodeAssignStatement(uncastLocalVariableRef, codeIndexerExpression);
						container.Statements.Add(buffAssignment);

						var converter = valueConverterAttributeModel.Attribute as ValueConverterAttribute;
						//Create the converter and then convert the value before everything else

						importNameSpace.Imports.Add(new CodeNamespaceImport(converter.Converter.Namespace));
						var converterCall = new CodeObjectCreateExpression(converter.Converter);
						var converterInstanceCall = new CodeMethodInvokeExpression(converterCall, "Convert",
							new CodeVariableReferenceExpression(variableName),
							new CodeTypeOfExpression(propertyInfoCache.PropertyType),
							new CodePrimitiveExpression(converter.Parameter),
							new CodeVariableReferenceExpression("System.Globalization.CultureInfo.CurrentCulture"));
						var codeAssignment = new CodeAssignStatement(new CodeVariableReferenceExpression(variableName),
							converterInstanceCall);
						container.Statements.Add(codeAssignment);
					}
					else
					{
						if (propertyInfoCache.PropertyType.IsEnum)
						{
							bufferVariable = new CodeVariableDeclarationStatement(typeof(object), variableName);
							container.Statements.Add(bufferVariable);
							uncastLocalVariableRef = new CodeVariableReferenceExpression(variableName);
							var setToValue = new CodeAssignStatement(refToProperty,
							new CodeCastExpression(
								new CodeTypeReference(propertyInfoCache.PropertyType, CodeTypeReferenceOptions.GenericTypeParameter),
									uncastLocalVariableRef));
							container.Statements.Add(setToValue);
						}
					}

					var isNullable = false;

					var baseType = Nullable.GetUnderlyingType(propertyInfoCache.PropertyType);

					if (baseType != null)
						isNullable = true;

					if (propertyInfoCache.PropertyType == typeof(string))
					{
						baseType = typeof(string);
					}
					else if (propertyInfoCache.PropertyType.IsArray)
					{
						baseType = propertyInfoCache.PropertyType;
					}

					if (baseType != null)
					{
						if (bufferVariable == null)
						{
							bufferVariable = new CodeVariableDeclarationStatement(typeof(object), variableName);
							container.Statements.Add(bufferVariable);
							uncastLocalVariableRef = new CodeVariableReferenceExpression(variableName);
							var buffAssignment = new CodeAssignStatement(uncastLocalVariableRef, codeIndexerExpression);
							container.Statements.Add(buffAssignment);
						}

						var checkForDbNull = new CodeConditionStatement
						{
							Condition = new CodeBinaryOperatorExpression(uncastLocalVariableRef,
								CodeBinaryOperatorType.IdentityEquality,
								new CodeFieldReferenceExpression(new CodeVariableReferenceExpression("System.DBNull"), "Value"))
						};

						CodeAssignStatement setToNull;
						if (!isNullable && baseType != typeof(string))
						{
							setToNull = new CodeAssignStatement(refToProperty,
							new CodeDefaultValueExpression(
								CreateShortCodeTypeReference(baseType, importNameSpace.Imports)));
						}
						else
						{
							setToNull = new CodeAssignStatement(refToProperty, new CodePrimitiveExpression(null));
						}

						var setToValue = new CodeAssignStatement(refToProperty,
							new CodeCastExpression(
								new CodeTypeReference(baseType, CodeTypeReferenceOptions.GenericTypeParameter),
								uncastLocalVariableRef));
						checkForDbNull.TrueStatements.Add(setToNull);
						checkForDbNull.FalseStatements.Add(setToValue);
						container.Statements.Add(checkForDbNull);
					}
					else
					{
						if (bufferVariable != null)
						{
							CodeExpression castExp = new CodeCastExpression(
						new CodeTypeReference(propertyInfoCache.PropertyType, CodeTypeReferenceOptions.GenericTypeParameter),
						new CodeVariableReferenceExpression(bufferVariable.Name));
							var setExpr = new CodeAssignStatement(refToProperty, castExp);
							container.Statements.Add(setExpr);
						}
						else
						{
							CodeExpression castExp = new CodeCastExpression(
		new CodeTypeReference(propertyInfoCache.PropertyType, CodeTypeReferenceOptions.GenericTypeParameter),
		codeIndexerExpression);
							var setExpr = new CodeAssignStatement(refToProperty, castExp);
							container.Statements.Add(setExpr);
						}

					}
				}
			}
		}
示例#9
0
        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);
        }
示例#10
0
        internal static Func <IDataRecord, object> CreateFactory(DbClassInfoCache target, FactoryHelperSettings settings)
        {
            var configAttrCtorAtt = target.Attributes.FirstOrDefault(s => s.Attribute is AutoGenerateCtorAttribute);
            AutoGenerateCtorAttribute classCtorAttr = null;

            if (configAttrCtorAtt != null)
            {
                classCtorAttr = configAttrCtorAtt.Attribute as AutoGenerateCtorAttribute;
            }

            CodeNamespace importNameSpace;

            importNameSpace = new CodeNamespace(target.Type.Namespace);
            var    cp = new CompilerParameters();
            string superName;
            var    compiler = new CodeTypeDeclaration();

            compiler.IsClass = true;

            var generateFactory = classCtorAttr != null &&
                                  classCtorAttr.CtorGeneratorMode == CtorGeneratorMode.FactoryMethod || target.Type.IsSealed;

            CodeMemberMethod codeConstructor;
            var codeName = target.Name.Split('.').Last();

            if (generateFactory)
            {
                codeConstructor     = GenerateFactory(target, settings, importNameSpace);
                superName           = codeName + "_Factory";
                compiler.Attributes = MemberAttributes.Static;
            }
            else
            {
                compiler.BaseTypes.Add(target.Type);
                codeConstructor    = GenerateConstructor(target, settings, importNameSpace);
                compiler.IsPartial = true;
                superName          = codeName + "_Super";
            }
            if (target.Constructors.Any(f => f.Arguments.Any()))
            {
                throw new TypeAccessException(
                          string.Format("Target type '{0}' does not define an public parametherless constructor. POCO's!!!!", target.Name));
            }

            compiler.Attributes |= MemberAttributes.Public;
            compiler.Name        = superName;
            compiler.Members.Add(codeConstructor);

            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);
                var compileUnit = new CodeCompileUnit();

                foreach (var defaultNamespace in settings.DefaultNamespaces)
                {
                    importNameSpace.Imports.Add(new CodeNamespaceImport(defaultNamespace));
                }

                foreach (
                    var additionalNamespace in
                    target.Attributes.Where(f => f.Attribute is AutoGenerateCtorNamespaceAttribute)
                    .Select(f => f.Attribute as AutoGenerateCtorNamespaceAttribute))
                {
                    importNameSpace.Imports.Add(new CodeNamespaceImport(additionalNamespace.UsedNamespace));
                }

                if (classCtorAttr != null && classCtorAttr.FullSateliteImport)
                {
                    foreach (var referencedAssembly in target.Type.Assembly.GetReferencedAssemblies())
                    {
                        cp.ReferencedAssemblies.Add(referencedAssembly.Name);
                    }
                }

                importNameSpace.Types.Add(compiler);

                compileUnit.Namespaces.Add(importNameSpace);
                var provider = new CSharpCodeProvider();
                var compileAssemblyFromDom = provider.CompileAssemblyFromDom(cp, compileUnit);

                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 (generateFactory)
                {
                    if (param.Length < 1)
                    {
                        return(false);
                    }
                    if (param.First().ParameterType != typeof(IDataRecord))
                    {
                        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();

            if (generateFactory)
            {
                il.Emit(OpCodes.Nop);
                il.Emit(OpCodes.Ldarg_0);
                il.Emit(OpCodes.Call, targetType.GetMethod("Factory"));
                il.Emit(OpCodes.Ret);
            }
            else
            {
                il.Emit(OpCodes.Ldarg_0);
                il.Emit(OpCodes.Newobj, matchingCtor);
                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);
        }
示例#11
0
        /// <summary>
        ///     Creates a new body in stlye of an Ado.net Constructor and attaches it to the <paramref name="target" />
        /// </summary>
        /// <param name="properties"></param>
        /// <param name="settings"></param>
        /// <param name="importNameSpace"></param>
        /// <param name="container"></param>
        /// <param name="target"></param>
        public static void GenerateBody(Dictionary <string, DbPropertyInfoCache> properties,
                                        FactoryHelperSettings settings,
                                        CodeNamespace importNameSpace,
                                        CodeMemberMethod container,
                                        CodeExpression target)
        {
            foreach (var propertyInfoCache in properties.Values)
            {
                propertyInfoCache.Refresh();

                var columnName = propertyInfoCache.DbName;

                if (settings.EnforcePublicPropertys)
                {
                    if (propertyInfoCache.Getter.MethodInfo.IsPrivate)
                    {
                        throw new AccessViolationException(string.Format(
                                                               "The Getter of {0} is private. Full creation cannot be enforced", propertyInfoCache.PropertyName));
                    }
                    if (propertyInfoCache.Setter.MethodInfo.IsPrivate)
                    {
                        throw new AccessViolationException(string.Format(
                                                               "The Setter of {0} is private. Full creation cannot be enforced", propertyInfoCache.PropertyName));
                    }
                }

                var codeIndexerExpression = new CodeIndexerExpression(new CodeVariableReferenceExpression("record"),
                                                                      new CodePrimitiveExpression(columnName));

                var variableName = columnName.ToLower();
                CodeVariableDeclarationStatement bufferVariable = null;

                //var propertyRef = new CodeVariableReferenceExpression(propertyInfoCache.PropertyName);

                var refToProperty = new CodeFieldReferenceExpression(target, propertyInfoCache.PropertyName);

                var attributes = propertyInfoCache.Attributes;
                var valueConverterAttributeModel =
                    attributes.FirstOrDefault(s => s.Attribute is ValueConverterAttribute);
                var isXmlProperty = attributes.FirstOrDefault(s => s.Attribute is FromXmlAttribute);
                CodeVariableReferenceExpression uncastLocalVariableRef = null;

                if (isXmlProperty != null)
                {
                    bufferVariable = new CodeVariableDeclarationStatement(typeof(object), variableName);
                    container.Statements.Add(bufferVariable);
                    uncastLocalVariableRef = new CodeVariableReferenceExpression(variableName);
                    var buffAssignment = new CodeAssignStatement(uncastLocalVariableRef, codeIndexerExpression);
                    container.Statements.Add(buffAssignment);

                    var checkXmlForNull = new CodeConditionStatement();
                    checkXmlForNull.Condition = new CodeBinaryOperatorExpression(
                        new CodeVariableReferenceExpression(variableName),
                        CodeBinaryOperatorType.IdentityInequality,
                        new CodeFieldReferenceExpression(new CodeVariableReferenceExpression("System.DBNull"), "Value"));
                    container.Statements.Add(checkXmlForNull);

                    var xmlRecordType = new CodeTypeReferenceExpression(typeof(XmlDataRecord));
                    importNameSpace.Imports.Add(new CodeNamespaceImport(typeof(DbClassInfoCache).Namespace));
                    importNameSpace.Imports.Add(new CodeNamespaceImport(typeof(DataConverterExtensions).Namespace));
                    importNameSpace.Imports.Add(new CodeNamespaceImport(typeof(DbConfigHelper).Namespace));

                    if (propertyInfoCache.CheckForListInterface())
                    {
                        var typeArgument      = propertyInfoCache.PropertyInfo.PropertyType.GetGenericArguments().FirstOrDefault();
                        var codeTypeOfListArg = new CodeTypeOfExpression(typeArgument);

                        var instanceHelper = new CodeMethodInvokeExpression(
                            new CodeTypeReferenceExpression(typeof(NonObservableDbCollection <>).MakeGenericType(typeArgument)),
                            "FromXml",
                            new CodeCastExpression(typeof(string), new CodeVariableReferenceExpression(variableName)));

                        //var tryParse = new CodeMethodInvokeExpression(xmlRecordType,
                        //	"TryParse",
                        //	new CodeCastExpression(typeof(string), uncastLocalVariableRef),
                        //	codeTypeOfListArg,
                        //	new CodePrimitiveExpression(false));

                        //var xmlDataRecords = new CodeMethodInvokeExpression(tryParse, "CreateListOfItems");
                        //var getClassInfo = new CodeMethodInvokeExpression(codeTypeOfListArg, "GetClassInfo");

                        //var xmlRecordsToObjects = new CodeMethodInvokeExpression(xmlDataRecords, "Select",
                        //	new CodeMethodReferenceExpression(getClassInfo, "SetPropertysViaReflection"));

                        //CodeObjectCreateExpression collectionCreate;
                        //if (typeArgument != null && (typeArgument.IsClass && typeArgument.GetInterface("INotifyPropertyChanged") != null))
                        //{
                        //	collectionCreate = new CodeObjectCreateExpression(typeof(DbCollection<>).MakeGenericType(typeArgument),
                        //		xmlRecordsToObjects);
                        //}
                        //else
                        //{
                        //	collectionCreate = new CodeObjectCreateExpression(typeof(NonObservableDbCollection<>).MakeGenericType(typeArgument),
                        //		xmlRecordsToObjects);
                        //}

                        var setExpr = new CodeAssignStatement(refToProperty, instanceHelper);
                        checkXmlForNull.TrueStatements.Add(setExpr);
                    }
                    else
                    {
                        var typeofProperty = new CodeTypeOfExpression(propertyInfoCache.PropertyType);
                        var getClassInfo   = new CodeMethodInvokeExpression(typeofProperty, "GetClassInfo");

                        var tryParse = new CodeMethodInvokeExpression(xmlRecordType,
                                                                      "TryParse",
                                                                      new CodeCastExpression(typeof(string), uncastLocalVariableRef),
                                                                      typeofProperty,
                                                                      new CodePrimitiveExpression(true));

                        var setProps = new CodeMethodInvokeExpression(getClassInfo, "SetPropertysViaReflection", tryParse,
                                                                      new CodeSnippetExpression("null"),
                                                                      new CodeSnippetExpression("null"));
                        var setExpr = new CodeAssignStatement(refToProperty,
                                                              new CodeCastExpression(propertyInfoCache.PropertyType, setProps));
                        checkXmlForNull.TrueStatements.Add(setExpr);
                    }
                }
                else
                {
                    //Should the SQL value be converted
                    if (valueConverterAttributeModel != null)
                    {
                        //create object buff123;
                        bufferVariable = new CodeVariableDeclarationStatement(typeof(object), variableName);
                        container.Statements.Add(bufferVariable);
                        //Assing buff123 = record[x]
                        uncastLocalVariableRef = new CodeVariableReferenceExpression(variableName);
                        var buffAssignment = new CodeAssignStatement(uncastLocalVariableRef, codeIndexerExpression);
                        container.Statements.Add(buffAssignment);

                        var converter = valueConverterAttributeModel.Attribute as ValueConverterAttribute;
                        //Create the converter and then convert the value before everything else

                        importNameSpace.Imports.Add(new CodeNamespaceImport(converter.Converter.Namespace));
                        var converterCall         = new CodeObjectCreateExpression(converter.Converter);
                        var converterInstanceCall = new CodeMethodInvokeExpression(converterCall, "Convert",
                                                                                   new CodeVariableReferenceExpression(variableName),
                                                                                   new CodeTypeOfExpression(propertyInfoCache.PropertyType),
                                                                                   new CodePrimitiveExpression(converter.Parameter),
                                                                                   new CodeVariableReferenceExpression("System.Globalization.CultureInfo.CurrentCulture"));
                        var codeAssignment = new CodeAssignStatement(new CodeVariableReferenceExpression(variableName),
                                                                     converterInstanceCall);
                        container.Statements.Add(codeAssignment);
                    }
                    else
                    {
                        if (propertyInfoCache.PropertyType.IsEnum)
                        {
                            bufferVariable = new CodeVariableDeclarationStatement(typeof(object), variableName);
                            container.Statements.Add(bufferVariable);
                            uncastLocalVariableRef = new CodeVariableReferenceExpression(variableName);
                            var setToValue = new CodeAssignStatement(refToProperty,
                                                                     new CodeCastExpression(
                                                                         new CodeTypeReference(propertyInfoCache.PropertyType, CodeTypeReferenceOptions.GenericTypeParameter),
                                                                         uncastLocalVariableRef));
                            container.Statements.Add(setToValue);
                        }
                    }

                    var isNullable = false;

                    var baseType = Nullable.GetUnderlyingType(propertyInfoCache.PropertyType);

                    if (baseType != null)
                    {
                        isNullable = true;
                    }

                    if (propertyInfoCache.PropertyType == typeof(string))
                    {
                        baseType = typeof(string);
                    }
                    else if (propertyInfoCache.PropertyType.IsArray)
                    {
                        baseType = propertyInfoCache.PropertyType;
                    }

                    if (baseType != null && !settings.AssertDataNotDbNull)
                    {
                        if (bufferVariable == null)
                        {
                            bufferVariable = new CodeVariableDeclarationStatement(typeof(object), variableName);
                            container.Statements.Add(bufferVariable);
                            uncastLocalVariableRef = new CodeVariableReferenceExpression(variableName);
                            var buffAssignment = new CodeAssignStatement(uncastLocalVariableRef, codeIndexerExpression);
                            container.Statements.Add(buffAssignment);
                        }

                        var checkForDbNull = new CodeConditionStatement
                        {
                            Condition = new CodeBinaryOperatorExpression(uncastLocalVariableRef,
                                                                         CodeBinaryOperatorType.IdentityEquality,
                                                                         new CodeFieldReferenceExpression(new CodeVariableReferenceExpression("System.DBNull"), "Value"))
                        };

                        CodeAssignStatement setToNull;
                        if (!isNullable && baseType != typeof(string))
                        {
                            setToNull = new CodeAssignStatement(refToProperty,
                                                                new CodeDefaultValueExpression(
                                                                    CreateShortCodeTypeReference(baseType, importNameSpace.Imports)));
                        }
                        else
                        {
                            setToNull = new CodeAssignStatement(refToProperty, new CodePrimitiveExpression(null));
                        }

                        var setToValue = new CodeAssignStatement(refToProperty,
                                                                 new CodeCastExpression(
                                                                     new CodeTypeReference(baseType, CodeTypeReferenceOptions.GenericTypeParameter),
                                                                     uncastLocalVariableRef));
                        checkForDbNull.TrueStatements.Add(setToNull);
                        checkForDbNull.FalseStatements.Add(setToValue);
                        container.Statements.Add(checkForDbNull);
                    }
                    else
                    {
                        if (bufferVariable != null)
                        {
                            CodeExpression castExp = new CodeCastExpression(
                                new CodeTypeReference(propertyInfoCache.PropertyType, CodeTypeReferenceOptions.GenericTypeParameter),
                                new CodeVariableReferenceExpression(bufferVariable.Name));
                            var setExpr = new CodeAssignStatement(refToProperty, castExp);
                            container.Statements.Add(setExpr);
                        }
                        else
                        {
                            CodeExpression castExp = new CodeCastExpression(
                                new CodeTypeReference(propertyInfoCache.PropertyType, CodeTypeReferenceOptions.GenericTypeParameter),
                                codeIndexerExpression);
                            var setExpr = new CodeAssignStatement(refToProperty, castExp);
                            container.Statements.Add(setExpr);
                        }
                    }
                }
            }
        }
示例#12
0
        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;
            }
        }