private void DisallowReturnTypeChange(CodeTypeReference baseType, CodeTypeReference newType) { if (Helper.IsCollectionType(Item.TypeUsage.EdmType) && GetCollectionKind(Item.TypeUsage) != CollectionKind.None) { if (newType == null) { throw EDesignUtil.InvalidOperation(Strings.CannotChangePropertyReturnTypeToNull(Item.Name, Item.DeclaringType.Name)); } // you can change the return type of collection properties // we don't even need to check return; } if (!(baseType == null && newType == null) && ( (baseType != null && !baseType.Equals(newType)) || (newType != null && !newType.Equals(baseType)) ) ) { throw EDesignUtil.InvalidOperation(Strings.CannotChangePropertyReturnType(Item.Name, Item.DeclaringType.Name)); } }
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; // grab the assemblies by location so that we don't compile against one that we didn't reference compilerParams.ReferencedAssemblies.AddRange(new string[] { typeof(System.CodeDom.Compiler.CodeDomProvider).Assembly.Location, // System.dll typeof(System.Linq.Enumerable).Assembly.Location, // System.Core.dll typeof(System.Data.Objects.ObjectContext).Assembly.Location, // System.Data.Entity.dll typeof(System.Data.Entity.Design.EntityCodeGenerator).Assembly.Location, // System.Data.Entity.Design.dll typeof(System.Data.DbType).Assembly.Location, // System.Data.dll typeof(System.Xml.XmlAttribute).Assembly.Location, // System.Xml.dll typeof(System.Xml.Linq.XElement).Assembly.Location, // 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 <CompilerError>().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 CodeMemberProperty CreateEntitySetProperty(EntitySet set) { Debug.Assert(set != null, "Property is Null"); // trying to get // // [System.ComponentModel.Browsable(false)] // public ObjectQuery<Customer> Customers // { // get // { // if ((this._Customers == null)) // { // this._Customers = base.CreateQuery<Customer>("[Customers]"); // } // return this._Customers; // } // } // CodeMemberProperty codeProperty = new CodeMemberProperty(); Generator.AttributeEmitter.EmitGeneratedCodeAttribute(codeProperty); codeProperty.Attributes = MemberAttributes.Final | GetEntitySetPropertyAccessibility(set); codeProperty.Name = set.Name; codeProperty.HasGet = true; codeProperty.HasSet = false; // Determine type to use for field/property and name of factory method on ObjectContext string typeName = "ObjectQuery"; string createMethodName = "CreateQuery"; // When the EntitySet name is used as CommandText, it should be quoted string createMethodArgument = "[" + set.Name + "]"; CodeTypeReference genericParameter = Generator.GetLeastPossibleQualifiedTypeReference(set.ElementType); codeProperty.Type = TypeReference.AdoFrameworkGenericClass(typeName, genericParameter); string fieldName = Utils.FieldNameFromPropName(set.Name); // raise the PropertyGenerated event before proceeding further PropertyGeneratedEventArgs eventArgs = new PropertyGeneratedEventArgs(set, fieldName, codeProperty.Type); Generator.RaisePropertyGeneratedEvent(eventArgs); if (eventArgs.ReturnType == null || !eventArgs.ReturnType.Equals(codeProperty.Type)) { throw EDesignUtil.InvalidOperation(Strings.CannotChangePropertyReturnType(set.Name, Item.Name)); } List <CodeAttributeDeclaration> additionalAttributes = eventArgs.AdditionalAttributes; if (additionalAttributes != null && additionalAttributes.Count > 0) { try { codeProperty.CustomAttributes.AddRange(additionalAttributes.ToArray()); } catch (ArgumentNullException e) { Generator.AddError(Strings.InvalidAttributeSuppliedForProperty(Item.Name), ModelBuilderErrorCode.InvalidAttributeSuppliedForProperty, EdmSchemaErrorSeverity.Error, e); } } // we need to insert user-specified code before other/existing code, including // the return statement List <CodeStatement> additionalGetStatements = eventArgs.AdditionalGetStatements; if (additionalGetStatements != null && additionalGetStatements.Count > 0) { try { codeProperty.GetStatements.AddRange(additionalGetStatements.ToArray()); } catch (ArgumentNullException e) { Generator.AddError(Strings.InvalidGetStatementSuppliedForProperty(Item.Name), ModelBuilderErrorCode.InvalidGetStatementSuppliedForProperty, EdmSchemaErrorSeverity.Error, e); } } codeProperty.GetStatements.Add( new CodeConditionStatement( EmitExpressionEqualsNull(new CodeFieldReferenceExpression(ThisRef, fieldName)), new CodeAssignStatement( new CodeFieldReferenceExpression(ThisRef, fieldName), new CodeMethodInvokeExpression( new CodeMethodReferenceExpression( new CodeBaseReferenceExpression(), createMethodName, new CodeTypeReference[] { genericParameter } ), new CodePrimitiveExpression(createMethodArgument) ) ) ) ); codeProperty.GetStatements.Add( new CodeMethodReturnStatement( new CodeFieldReferenceExpression( ThisRef, fieldName ) ) ); // property summary CommentEmitter.EmitSummaryComments(set, codeProperty.Comments); return(codeProperty); }
private void GenerateCodeCommon(MetadataArtifactLoader sourceLoader, List <MetadataArtifactLoader> loaders, LazyTextWriterCreator target, string sourceEdmSchemaFilePath, string targetFilePath, bool closeReaders, List <EdmSchemaError> errors) { MetadataArtifactLoaderComposite composite = new MetadataArtifactLoaderComposite(loaders); // create the schema manager from the xml readers Dictionary <MetadataArtifactLoader, XmlReader> readerSourceMap = new Dictionary <MetadataArtifactLoader, XmlReader>(); IList <Schema> schemas; List <XmlReader> readers = composite.GetReaders(readerSourceMap); try { IList <EdmSchemaError> schemaManagerErrors = SchemaManager.ParseAndValidate(readers, composite.GetPaths(), SchemaDataModelOption.EntityDataModel, EdmProviderManifest.Instance, out schemas); errors.AddRange(schemaManagerErrors); } finally { if (closeReaders) { MetadataUtil.DisposeXmlReaders(readers); } } ThrowOnAnyNonWarningErrors(errors); Debug.Assert(readerSourceMap.ContainsKey(sourceLoader), "the source loader didn't produce any of the xml readers..."); XmlReader sourceReader = readerSourceMap[sourceLoader]; // use the index of the "source" xml reader as the index of the "source" schema Debug.Assert(readers.Contains(sourceReader), "the source reader is not in the list of readers"); int index = readers.IndexOf(sourceReader); Debug.Assert(index >= 0, "couldn't find the source reader in the list of readers"); Debug.Assert(readers.Count == schemas.Count, "We have a different number of readers than schemas"); Schema sourceSchema = schemas[index]; Debug.Assert(sourceSchema != null, "sourceSchema is null"); // create the EdmItemCollection from the schemas EdmItemCollection itemCollection = new EdmItemCollection(schemas); if (EntityFrameworkVersionsUtil.ConvertToVersion(itemCollection.EdmVersion) >= EntityFrameworkVersions.Version2) { throw EDesignUtil.InvalidOperation(Strings.TargetEntityFrameworkVersionToNewForEntityClassGenerator); } // generate code ClientApiGenerator generator = new ClientApiGenerator(sourceSchema, itemCollection, this, errors); generator.GenerateCode(target, targetFilePath); }