EntityCodeGenerator.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / DataEntityDesign / Design / System / Data / Entity / Design / EntityCodeGenerator.cs / 1305376 / EntityCodeGenerator.cs

                            //---------------------------------------------------------------------- 
// 
//      Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// 
// @owner       [....]
// @backupOwner [....] 
//--------------------------------------------------------------------- 
//#define ENABLE_TEMPLATE_DEBUGGING
using System; 
using System.Collections.Generic;
using System.Text;
using System.Data.Entity.Design.Common;
using System.Data.Metadata.Edm; 
using System.Linq;
using System.CodeDom.Compiler; 
using System.Data.Entity.Design.SsdlGenerator; 
using System.IO;
using System.Reflection; 
using System.Globalization;
using System.Diagnostics;
using System.Xml;
using System.Runtime.Versioning; 
using System.Threading;
 
namespace System.Data.Entity.Design 
{
    public class EntityCodeGenerator 
    {
        private LanguageOption _languageOption = LanguageOption.GenerateCSharpCode;
        private EdmToObjectNamespaceMap _edmToObjectNamespaceMap = new EdmToObjectNamespaceMap();
 

        public EntityCodeGenerator(LanguageOption languageOption) 
        { 
            _languageOption = EDesignUtil.CheckLanguageOptionArgument(languageOption, "languageOption");
        } 

        public LanguageOption LanguageOption
        {
            get { return _languageOption; } 
            set { _languageOption = EDesignUtil.CheckLanguageOptionArgument(value, "value"); }
        } 
 
        /// 
        /// Gets the map entries use to customize the namespace of .net types that are generated 
        /// and referenced by the generated code
        /// 
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Edm")]
        public EdmToObjectNamespaceMap EdmToObjectNamespaceMap 
        {
            get { return _edmToObjectNamespaceMap; } 
        } 

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Edm")] 
        [ResourceExposure(ResourceScope.Machine)] // for sourceEdmSchemaFilePath, targetPath and additionalEdmSchema which are machine resources
        [ResourceConsumption(ResourceScope.Machine)] // for InternalGenerateCode method call. But the path is not created in this method.
        public IList GenerateCode(string sourceEdmSchemaFilePath, string targetPath, IEnumerable additionalEdmSchemaFilePaths)
        { 
            EntityUtil.CheckStringArgument(sourceEdmSchemaFilePath, "sourceEdmSchemaFilePath");
            EDesignUtil.CheckArgumentNull(additionalEdmSchemaFilePaths, "additionalEdmSchemaFilePaths"); 
            EntityUtil.CheckStringArgument(targetPath, "targetPath"); 

            return InternalGenerateCode(sourceEdmSchemaFilePath, new LazyTextWriterCreator(targetPath), additionalEdmSchemaFilePaths); 
        }

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Edm")]
        [ResourceExposure(ResourceScope.Machine)] // for sourceEdmSchemaFilePath and targetPath which are Machine resources 
        [ResourceConsumption(ResourceScope.Machine)] // for InternalGenerateCode method call. But the path is not created in this method.
        public IList GenerateCode(string sourceEdmSchemaFilePath, string targetPath) 
        { 
            EntityUtil.CheckStringArgument(sourceEdmSchemaFilePath, "sourceEdmSchemaFilePath");
            EntityUtil.CheckStringArgument(targetPath, "targetPath"); 
            return InternalGenerateCode(sourceEdmSchemaFilePath, new LazyTextWriterCreator(targetPath), null);
        }

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Edm")] 
        [ResourceConsumption(ResourceScope.Machine)] // temp file creation, and passing to InternalGenerateCode
        public IList GenerateCode(XmlReader sourceEdmSchema, TextWriter target) 
        { 
            EDesignUtil.CheckArgumentNull(sourceEdmSchema, "sourceEdmSchema");
            EDesignUtil.CheckArgumentNull(target, "target"); 
            using (TempFileCollection collection = new TempFileCollection())
            {
                string tempSourceEdmSchemaPath = collection.AddExtension(XmlConstants.CSpaceSchemaExtension);
                SaveXmlReaderToFile(sourceEdmSchema, tempSourceEdmSchemaPath); 

                return InternalGenerateCode(tempSourceEdmSchemaPath, new LazyTextWriterCreator(target), null); 
            } 
        }
 
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Edm")]
        [ResourceConsumption(ResourceScope.Machine)] //Temp file creation, and passing to InternalGenerateCode
        public IList GenerateCode(XmlReader sourceEdmSchema, TextWriter target, IEnumerable additionalEdmSchemas)
        { 
            EDesignUtil.CheckArgumentNull(sourceEdmSchema, "sourceEdmSchema");
            EDesignUtil.CheckArgumentNull(additionalEdmSchemas, "additionalEdmSchemas"); 
            EDesignUtil.CheckArgumentNull(target, "target"); 
            using (TempFileCollection collection = new TempFileCollection())
            { 
                string tempSourceEdmSchemaPath = collection.AddExtension(XmlConstants.CSpaceSchemaExtension);
                SaveXmlReaderToFile(sourceEdmSchema, tempSourceEdmSchemaPath);
                List additionalTempPaths = new List();
                foreach (XmlReader reader in additionalEdmSchemas) 
                {
 
                    string temp = Path.GetTempFileName() + XmlConstants.CSpaceSchemaExtension; 
                    SaveXmlReaderToFile(reader, temp);
                    additionalTempPaths.Add(temp); 
                    collection.AddFile(temp, false);
                }
                return InternalGenerateCode(tempSourceEdmSchemaPath, new LazyTextWriterCreator(target), additionalTempPaths);
            } 
        }
 
        private IList InternalGenerateCode(string sourceEdmSchemaFilePath, LazyTextWriterCreator textWriter, IEnumerable additionalEdmSchemaFilePaths) 
        {
            List errors = new List(); 

            try
            {
                ReflectionAdapter codeGenerator = ReflectionAdapter.Create(_languageOption); 
                codeGenerator.SourceCsdlPath = sourceEdmSchemaFilePath;
                codeGenerator.ReferenceCsdlPaths = additionalEdmSchemaFilePaths; 
                codeGenerator.EdmToObjectNamespaceMap = _edmToObjectNamespaceMap.AsDictionary(); 

                string code = codeGenerator.TransformText(); 

                if (codeGenerator.SourceEdmVersion == XmlConstants.EdmVersionForV1_1)
                {
                    return GenerateCodeFor1_1Schema(sourceEdmSchemaFilePath, textWriter, additionalEdmSchemaFilePaths); 
                }
 
                if (codeGenerator.Errors.Count != 0) 
                {
                    ModelBuilderErrorCode errorCode = ModelBuilderErrorCode.PreprocessTemplateTransformationError; 
                    errors.AddRange(codeGenerator.Errors.OfType().Select(c => ConvertToEdmSchemaError(c, errorCode)));

                    if (codeGenerator.Errors.HasErrors)
                        return errors; 
                }
 
 
                using (TextWriter writer = textWriter.GetOrCreateTextWriter())
                { 
                    writer.Write(code);
                }
            }
            catch (System.UnauthorizedAccessException ex) 
            {
                errors.Add(EntityClassGenerator.CreateErrorForException(ModelBuilderErrorCode.SecurityError, ex)); 
            } 
            catch (System.IO.FileNotFoundException ex)
            { 
                errors.Add(EntityClassGenerator.CreateErrorForException(ModelBuilderErrorCode.FileNotFound, ex));
            }
            catch (System.Security.SecurityException ex)
            { 
                errors.Add(EntityClassGenerator.CreateErrorForException(ModelBuilderErrorCode.SecurityError, ex));
            } 
            catch (System.IO.DirectoryNotFoundException ex) 
            {
                errors.Add(EntityClassGenerator.CreateErrorForException(ModelBuilderErrorCode.DirectoryNotFound, ex)); 
            }
            catch (System.IO.IOException ex)
            {
                errors.Add(EntityClassGenerator.CreateErrorForException(ModelBuilderErrorCode.IOException, ex)); 
            }
            catch (Exception e) 
            { 
                if (MetadataUtil.IsCatchableExceptionType(e))
                { 
                    errors.Add(EntityClassGenerator.CreateErrorForException(ModelBuilderErrorCode.PreprocessTemplateTransformationError, e, sourceEdmSchemaFilePath));
                }
                else
                { 
                    throw;
                } 
            } 

            return errors; 
        }

        private IList GenerateCodeFor1_1Schema(string sourceEdmSchemaFilePath, LazyTextWriterCreator textWriter, IEnumerable additionalEdmSchemaFilePaths)
        { 
            EntityClassGenerator generator = new EntityClassGenerator(_languageOption);
            string target = textWriter.TargetFilePath; 
            bool cleanUpTarget = false; 
            try
            { 
                if (textWriter.IsUserSuppliedTextWriter)
                {
                    cleanUpTarget = true;
                    target = Path.Combine(Path.GetTempPath(), Path.GetTempFileName()); 

                } 
 
                IList errors = generator.GenerateCode(sourceEdmSchemaFilePath, target, additionalEdmSchemaFilePaths != null ? additionalEdmSchemaFilePaths : Enumerable.Empty());
 
                if (textWriter.IsUserSuppliedTextWriter && !errors.Any(e => e.Severity == EdmSchemaErrorSeverity.Error))
                {
                    textWriter.GetOrCreateTextWriter().Write(File.ReadAllText(target));
                } 

                return errors; 
            } 
            finally
            { 
                if (cleanUpTarget && target != null && File.Exists(target))
                {
                    File.Delete(target);
                } 
            }
 
        } 

        private static void SaveXmlReaderToFile(XmlReader schema, string tempSchemaPath) 
        {
            using (XmlWriter writer = XmlWriter.Create(tempSchemaPath))
            {
                writer.WriteNode(schema, false); 
            }
        } 
 
        private static EdmSchemaError ConvertToEdmSchemaError(CompilerError error, ModelBuilderErrorCode defaultErrorCode)
        { 
            int errorNumber;
            string message = error.ErrorText;
            bool usePositionInfo = true;
            EdmSchemaErrorSeverity severity = error.IsWarning ? EdmSchemaErrorSeverity.Warning : EdmSchemaErrorSeverity.Error; 
            if (int.TryParse(error.ErrorNumber, out errorNumber))
            { 
                if (error.Line == -1 && error.Column == -1) 
                {
                    usePositionInfo = false; 
                }
            }
            else
            { 
                message = String.Format(CultureInfo.InvariantCulture, "{0}({1})", error.ErrorText, error.ErrorNumber);
                errorNumber = (int)defaultErrorCode; 
            } 

            if (usePositionInfo) 
            {
                return new EdmSchemaError(message,
                                        errorNumber,
                                        severity, 
                                        error.FileName,
                                        error.Line, 
                                        error.Column); 
            }
            else 
            {
                return new EdmSchemaError(message,
                                        errorNumber,
                                        severity); 
            }
        } 
 

        static Type _vbCodeGeneratorType = null; 
        static Type _csharpCodeGeneratorType = null;
        // there is a bug in the TextTemplateFilePreprocessor that makes the type name camel case
        private const string CSharpTemplateCodeGenType = "TemplateCodeGenerators.CSharpCodeGenTemplate";
        private const string CSharpTemplateCodeGenResource = CSharpTemplateCodeGenType + ".cs"; 
        private const string VBTemplateCodeGenType = "TemplateCodeGenerators.VBCodeGenTemplate";
        private const string VBTemplateCodeGenResource = VBTemplateCodeGenType + ".vb"; 
        private static object CreateCSharpCodeGenerator() 
        {
            if (_csharpCodeGeneratorType == null) 
            {
                Type type = CreateCodeGeneratorType(new Microsoft.CSharp.CSharpCodeProvider(), CSharpTemplateCodeGenResource, CSharpTemplateCodeGenType);
                Interlocked.Exchange(ref _csharpCodeGeneratorType, type);
            } 

            return Activator.CreateInstance(_csharpCodeGeneratorType); 
        } 

        private static object CreateVBCodeGenerator() 
        {
            if (_vbCodeGeneratorType == null)
            {
                Type type = CreateCodeGeneratorType(new Microsoft.VisualBasic.VBCodeProvider(), VBTemplateCodeGenResource, VBTemplateCodeGenType); 
                Interlocked.Exchange(ref _vbCodeGeneratorType, type);
            } 
 
            return Activator.CreateInstance(_vbCodeGeneratorType);
        } 

        private static Type CreateCodeGeneratorType(System.CodeDom.Compiler.CodeDomProvider compilerProvider, string resourceName, string typeName)
        {
            string sourceCode = null; 
            using (Stream sourceStream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName))
            using (StreamReader reader = new StreamReader(sourceStream)) 
            { 
                sourceCode = reader.ReadToEnd();
            } 

            CompilerParameters compilerParams = new CompilerParameters();
            compilerParams.CompilerOptions = "/d:PREPROCESSED_TEMPLATE";
            compilerParams.GenerateInMemory = true; 
            compilerParams.GenerateExecutable = false;
            compilerParams.ReferencedAssemblies.AddRange(new string[] { 
                        "System.dll", 
                        "System.Core.dll",
                        "System.Runtime.Serialization.dll", 
                        "System.Data.Entity.dll",
                        "System.Data.Entity.Design.dll",
                        "System.Data.dll",
                        "System.Xml.dll", 
                        "System.Xml.Linq.dll",
                }); 
 
#if !ENABLE_TEMPLATE_DEBUGGING
            CompilerResults results = compilerProvider.CompileAssemblyFromSource(compilerParams, sourceCode); 
#else
            // enables debugging
            compilerParams.GenerateInMemory = false;
            compilerParams.IncludeDebugInformation = true; 
            string baseName = Path.GetFileNameWithoutExtension(Path.GetTempFileName()) + ".";
            compilerParams.OutputAssembly = Path.Combine(Path.GetTempPath(), baseName + typeName + ".Assembly.dll"); 
            string sourceFileName = Path.Combine(Path.GetTempPath(), baseName + typeName + ".Source." + compilerProvider.FileExtension); 
            File.WriteAllText(sourceFileName, sourceCode);
            CompilerResults results = compilerProvider.CompileAssemblyFromFile(compilerParams, sourceFileName); 
#warning DO NOT CHECK IN LIKE THIS, Dynamic Assembly Debugging is enabled
#endif

 
            if (results.Errors.HasErrors)
            { 
                string message = results.Errors.OfType().Aggregate(string.Empty, (accumulated, input) => accumulated == string.Empty ? input.ToString() : accumulated + Environment.NewLine + input.ToString()); 
                throw EDesignUtil.InvalidOperation(message);
            } 

            return results.CompiledAssembly.GetType(typeName);
        }
 

 
        private class ReflectionAdapter 
        {
            private object _instance; 
            private MethodInfo _transformText;
            private PropertyInfo _sourceCsdlPath;
            private PropertyInfo _referenceCsdlPaths;
            private PropertyInfo _errors; 
            private PropertyInfo _edmToObjectNamespaceMap;
            private PropertyInfo _sourceEdmVersion; 
 
            internal ReflectionAdapter(object instance)
            { 
                _instance = instance;
                Type type = _instance.GetType();
                BindingFlags flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy;
                _transformText = type.GetMethod("TransformText", flags, null, new Type[0], null); 
                Debug.Assert(_transformText != null, "Unable to find method, did the signature or name change?");
 
                _sourceCsdlPath = type.GetProperty("SourceCsdlPath", flags, null, typeof(String), new Type[0], null); 
                Debug.Assert(_sourceCsdlPath != null, "Unable to find property, did the signature or name change?");
 
                _referenceCsdlPaths = type.GetProperty("ReferenceCsdlPaths", flags, null, typeof(IEnumerable), new Type[0], null);
                Debug.Assert(_referenceCsdlPaths != null, "Unable to find property, did the signature or name change?");

                _errors = type.GetProperty("Errors", flags, null, typeof(CompilerErrorCollection), new Type[0], null); 
                Debug.Assert(_errors != null, "Unable to find property, did the signature or name change?");
 
                _edmToObjectNamespaceMap = type.GetProperty("EdmToObjectNamespaceMap", flags, null, typeof(Dictionary), new Type[0], null); 
                Debug.Assert(_edmToObjectNamespaceMap != null, "Unable to find property, did the signature or name change?");
 
                _sourceEdmVersion = type.GetProperty("SourceEdmVersion", flags, null, typeof(Double), new Type[0], null);
                Debug.Assert(_sourceEdmVersion != null, "Unable to find property, did the signature or name change?");
            }
 
            internal CompilerErrorCollection Errors
            { 
                get { return (CompilerErrorCollection)_errors.GetValue(_instance, null); } 
            }
 
            internal IEnumerable ReferenceCsdlPaths
            {
                set
                { 
                    _referenceCsdlPaths.SetValue(_instance, value, null);
                } 
            } 

            internal string SourceCsdlPath 
            {
                get
                {
                    return (String)_sourceCsdlPath.GetValue(_instance, null); 
                }
                set 
                { 
                    _sourceCsdlPath.SetValue(_instance, value, null);
                } 
            }

            internal Dictionary EdmToObjectNamespaceMap
            { 
                set { _edmToObjectNamespaceMap.SetValue(_instance, value, null); }
            } 
 
            internal Double SourceEdmVersion
            { 
                get { return (Double)_sourceEdmVersion.GetValue(_instance, null); }
            }

            internal string TransformText() 
            {
                try 
                { 
                    return (string)_transformText.Invoke(_instance, new object[0]);
                } 
                catch (TargetInvocationException e)
                {
                    Exception actual = e.InnerException != null ? e.InnerException : e;
 
                    System.CodeDom.Compiler.CompilerError error = new System.CodeDom.Compiler.CompilerError();
                    error.ErrorText = actual.Message; 
                    error.IsWarning = false; 
                    error.FileName = SourceCsdlPath;
                    Errors.Add(error); 

                    return string.Empty;
                }
 
            }
 
            internal static ReflectionAdapter Create(LanguageOption language) 
            {
                if (language == LanguageOption.GenerateCSharpCode) 
                {
                    return new ReflectionAdapter(CreateCSharpCodeGenerator());
                }
                else 
                {
                    Debug.Assert(language == LanguageOption.GenerateVBCode, "Did you add a new option?"); 
                    return new ReflectionAdapter(CreateVBCodeGenerator()); 
                }
            } 
        }
    }
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.


                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK