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 IListGenerateCode(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
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- Suspend.cs
- OperationResponse.cs
- ScriptMethodAttribute.cs
- WmlTextBoxAdapter.cs
- XmlChildEnumerator.cs
- Double.cs
- TreeViewHitTestInfo.cs
- InputLangChangeRequestEvent.cs
- HwndMouseInputProvider.cs
- ConnectionPoint.cs
- TextCollapsingProperties.cs
- DropTarget.cs
- DelegatingHeader.cs
- MessageDecoder.cs
- BufferedGraphicsContext.cs
- ButtonField.cs
- TargetInvocationException.cs
- DllHostedComPlusServiceHost.cs
- XmlSiteMapProvider.cs
- BulletedListEventArgs.cs
- CodeChecksumPragma.cs
- ImageCodecInfoPrivate.cs
- TextSpanModifier.cs
- IERequestCache.cs
- LinkTarget.cs
- RepeatBehaviorConverter.cs
- EmptyStringExpandableObjectConverter.cs
- DescendentsWalkerBase.cs
- DataControlButton.cs
- MetadataCacheItem.cs
- SingleObjectCollection.cs
- TimeSpanSecondsConverter.cs
- ExceptionUtility.cs
- EventWaitHandleSecurity.cs
- wgx_render.cs
- CodeBlockBuilder.cs
- Int32CAMarshaler.cs
- EdmProviderManifest.cs
- FileVersion.cs
- SizeAnimationClockResource.cs
- TableRowCollection.cs
- Verify.cs
- ImageClickEventArgs.cs
- Input.cs
- WinCategoryAttribute.cs
- EventProxy.cs
- XPathConvert.cs
- Image.cs
- TextModifierScope.cs
- CompilerResults.cs
- FileLoadException.cs
- TextBox.cs
- ConsoleKeyInfo.cs
- SiteOfOriginPart.cs
- BulletedListEventArgs.cs
- ProjectionCamera.cs
- DrawingAttributesDefaultValueFactory.cs
- ExtentKey.cs
- DataGridViewComboBoxCell.cs
- CqlWriter.cs
- ErrorBehavior.cs
- XmlLoader.cs
- ObjectViewEntityCollectionData.cs
- ComponentCollection.cs
- PageCatalogPart.cs
- OdbcPermission.cs
- TreeBuilderXamlTranslator.cs
- PackagePartCollection.cs
- FilteredDataSetHelper.cs
- CodeMemberEvent.cs
- WpfXamlMember.cs
- GradientBrush.cs
- TokenBasedSetEnumerator.cs
- EventPrivateKey.cs
- ComponentChangingEvent.cs
- ToolBarButton.cs
- ImageCollectionCodeDomSerializer.cs
- PhysicalFontFamily.cs
- NonSerializedAttribute.cs
- SortedDictionary.cs
- SelectionHighlightInfo.cs
- TdsParserSafeHandles.cs
- SortKey.cs
- HandleRef.cs
- PackageRelationshipSelector.cs
- DesignerDataStoredProcedure.cs
- PageThemeBuildProvider.cs
- AssociationEndMember.cs
- CodeCatchClauseCollection.cs
- TextDecorationCollection.cs
- RawStylusActions.cs
- StandardOleMarshalObject.cs
- CustomAttributeFormatException.cs
- TemplateApplicationHelper.cs
- HtmlSelect.cs
- Normalization.cs
- ParallelRangeManager.cs
- WindowShowOrOpenTracker.cs
- WorkflowRuntimeEndpoint.cs
- EventHandlerList.cs