/// <summary> /// Gets a <see cref="CodeTypeReference"/> for a CLR type. /// </summary> /// <param name="type">A CLR type.</param> /// <param name="codegenContext">A <see cref="ClientProxyGenerator"/>.</param> /// <param name="referencingType">The referencing type.</param> /// <returns>A <see cref="CodeTypeReference"/> for a CLR type.</returns> public static CodeTypeReference GetTypeReference(Type type, ICodeGenContext codegenContext, CodeTypeDeclaration referencingType) { if (type.IsPrimitive || type == typeof(void) || type == typeof(decimal) || type == typeof(string) || type == typeof(object)) { return(new CodeTypeReference(type)); } if (codegenContext != null && referencingType != null) { CodeNamespace ns = codegenContext.GetNamespace(referencingType); if (ns != null && !ns.Name.Equals(type.Namespace)) { // If the namespace is already imported, the following line will be a no-op. ns.Imports.Add(new CodeNamespaceImport(type.Namespace)); } } if (type.IsArray) { return(new CodeTypeReference( CodeGenUtilities.GetTypeReference(type.GetElementType(), codegenContext, referencingType), type.GetArrayRank())); } if (type.IsGenericType) { Type[] genericArguments = type.GetGenericArguments(); CodeTypeReference[] typeArguments = new CodeTypeReference[genericArguments.Length]; for (int i = 0; i < genericArguments.Length; i++) { typeArguments[i] = GetTypeReference(genericArguments[i]); } return(new CodeTypeReference(type.Name, typeArguments)); } return(new CodeTypeReference(type.Name)); }
/// <summary> /// Gets a <see cref="CodeTypeReference"/> for a CLR type. /// </summary> /// <param name="type">A CLR type.</param> /// <param name="codegenContext">A <see cref="ClientProxyGenerator"/>.</param> /// <param name="referencingType">The referencing type.</param> /// <returns>A <see cref="CodeTypeReference"/> for a CLR type.</returns> public static CodeTypeReference GetTypeReference(Type type, ICodeGenContext codegenContext, CodeTypeDeclaration referencingType) { if (type.IsPrimitive || type == typeof(void) || type == typeof(decimal) || type == typeof(string) || type == typeof(object)) { return new CodeTypeReference(type); } if (codegenContext != null && referencingType != null) { CodeNamespace ns = codegenContext.GetNamespace(referencingType); if (ns != null && !ns.Name.Equals(type.Namespace)) { // If the namespace is already imported, the following line will be a no-op. ns.Imports.Add(new CodeNamespaceImport(type.Namespace)); } } if (type.IsArray) { return new CodeTypeReference( CodeGenUtilities.GetTypeReference(type.GetElementType(), codegenContext, referencingType), type.GetArrayRank()); } if (type.IsGenericType) { Type[] genericArguments = type.GetGenericArguments(); CodeTypeReference[] typeArguments = new CodeTypeReference[genericArguments.Length]; for (int i = 0; i < genericArguments.Length; i++) { typeArguments[i] = GetTypeReference(genericArguments[i]); } return new CodeTypeReference(type.Name, typeArguments); } return new CodeTypeReference(type.Name); }
/// <summary> /// Generates the GetEntityState helper method that allows POCO types to retrieve their /// entity state from the contect. It is not available on the POCO types directly. /// </summary> /// <param name="codeGenContext">The context in which we are generating code.</param> /// <param name="businessLogicClass">The class we are generating.</param> /// <returns>The <see cref="CodeTypeMember"/> containing the helper method.</returns> private static CodeTypeMember GenerateGetEntityState(ICodeGenContext codeGenContext, CodeTypeDeclaration businessLogicClass) { // Add an import for System.Data.Objects CodeNamespace codeNamespace = codeGenContext.GetNamespace(businessLogicClass); if (codeNamespace != null) { codeNamespace.Imports.Add(new CodeNamespaceImport("System.Data.Objects")); } //private EntityState GetEntityState(object entity) //{ // ObjectStateEntry stateEntry = null; // if (!this.ObjectContext.ObjectStateManager.TryGetObjectStateEntry(entity, out stateEntry)) // { // return EntityState.Detached; // } // return stateEntry.State; //} // Declaration CodeMemberMethod method = new CodeMemberMethod(); method.Name = LinqToEntitiesContext.GetEntityStateHelperMethodName; method.ReturnType = new CodeTypeReference(typeof(EntityState).Name); method.Attributes = MemberAttributes.Private; method.Parameters.Add(new CodeParameterDeclarationExpression(typeof(object), "entity")); // ObjectStateEntry stateEntry = null; method.Statements.Add(new CodeVariableDeclarationStatement("ObjectStateEntry", "stateEntry", new CodePrimitiveExpression(null))); CodeArgumentReferenceExpression entityArgRef = new CodeArgumentReferenceExpression("entity"); CodeExpression contextRef = new CodePropertyReferenceExpression(new CodeThisReferenceExpression(), "ObjectContext"); CodeFieldReferenceExpression detachedStateRef = new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(typeof(EntityState).Name), Enum.GetName(typeof(EntityState), EntityState.Detached)); CodePropertyReferenceExpression objectStateMgrRef = new CodePropertyReferenceExpression(contextRef, "ObjectStateManager"); CodeVariableReferenceExpression entityStateRef = new CodeVariableReferenceExpression("stateEntry"); // The "_out_" prefix will be replaced below with the language-appropriate modifier to make an out param. // CodeDom does not support this, so we must do some string manipulation CodeVariableReferenceExpression outEntityStateRef = new CodeVariableReferenceExpression("_out_stateEntry"); // this.ObjectContext.ObjectStateManager.TryGetObjectStateEntry(entity, out stateEntry) CodeMethodInvokeExpression getObjectStateEntryCall = new CodeMethodInvokeExpression(objectStateMgrRef, "TryGetObjectStateEntry", entityArgRef, outEntityStateRef); // if (...TryGet()) CodeExpression tryGetTest = CodeGenUtilities.MakeEqual(typeof(bool), getObjectStateEntryCall, new CodePrimitiveExpression(false), codeGenContext.IsCSharp); // if (...TryGet..) { return EntityState.Detached; } CodeMethodReturnStatement returnDetached = new CodeMethodReturnStatement(detachedStateRef); CodeConditionStatement ifTryGet = new CodeConditionStatement(tryGetTest, returnDetached); method.Statements.Add(ifTryGet); // Return entityState.State; method.Statements.Add(new CodeMethodReturnStatement(new CodePropertyReferenceExpression(entityStateRef, "State"))); // CodeDom does not support specifying 'out' parameters at the method call site. // So convert the entire method into a snippet of text StringBuilder snippet = null; CodeDomProvider provider = codeGenContext.Provider; using (StringWriter snippetWriter = new StringWriter(System.Globalization.CultureInfo.CurrentCulture)) { provider.GenerateCodeFromMember(method, snippetWriter, codeGenContext.CodeGeneratorOptions); snippet = snippetWriter.GetStringBuilder(); } // Our convention above is that "_out_" will be replaced by the language-appropriate "out" parameter modifier. // In the case of VB, it is the default snippet.Replace("_out_", codeGenContext.IsCSharp ? "out " : string.Empty); // We need to indent the entire snippet 2 levels string indent = codeGenContext.CodeGeneratorOptions.IndentString; indent += indent; string snippetText = indent + snippet.ToString().Replace(Environment.NewLine, Environment.NewLine + indent).TrimEnd(' '); CodeSnippetTypeMember methodAsText = new CodeSnippetTypeMember(snippetText); return methodAsText; }
/// <summary> /// Generates the GetEntityState helper method that allows POCO types to retrieve their /// entity state from the contect. It is not available on the POCO types directly. /// </summary> /// <param name="codeGenContext">The context in which we are generating code.</param> /// <param name="businessLogicClass">The class we are generating.</param> /// <returns>The <see cref="CodeTypeMember"/> containing the helper method.</returns> private static CodeTypeMember GenerateGetEntityState(ICodeGenContext codeGenContext, CodeTypeDeclaration businessLogicClass) { // Add an import for System.Data.Objects CodeNamespace codeNamespace = codeGenContext.GetNamespace(businessLogicClass); if (codeNamespace != null) { codeNamespace.Imports.Add(new CodeNamespaceImport("System.Data.Objects")); } //private EntityState GetEntityState(object entity) //{ // ObjectStateEntry stateEntry = null; // if (!this.ObjectContext.ObjectStateManager.TryGetObjectStateEntry(entity, out stateEntry)) // { // return EntityState.Detached; // } // return stateEntry.State; //} // Declaration CodeMemberMethod method = new CodeMemberMethod(); method.Name = LinqToEntitiesContext.GetEntityStateHelperMethodName; method.ReturnType = new CodeTypeReference(typeof(EntityState).Name); method.Attributes = MemberAttributes.Private; method.Parameters.Add(new CodeParameterDeclarationExpression(typeof(object), "entity")); // ObjectStateEntry stateEntry = null; method.Statements.Add(new CodeVariableDeclarationStatement("ObjectStateEntry", "stateEntry", new CodePrimitiveExpression(null))); CodeArgumentReferenceExpression entityArgRef = new CodeArgumentReferenceExpression("entity"); CodeExpression contextRef = new CodePropertyReferenceExpression(new CodeThisReferenceExpression(), "ObjectContext"); CodeFieldReferenceExpression detachedStateRef = new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(typeof(EntityState).Name), Enum.GetName(typeof(EntityState), EntityState.Detached)); CodePropertyReferenceExpression objectStateMgrRef = new CodePropertyReferenceExpression(contextRef, "ObjectStateManager"); CodeVariableReferenceExpression entityStateRef = new CodeVariableReferenceExpression("stateEntry"); // The "_out_" prefix will be replaced below with the language-appropriate modifier to make an out param. // CodeDom does not support this, so we must do some string manipulation CodeVariableReferenceExpression outEntityStateRef = new CodeVariableReferenceExpression("_out_stateEntry"); // this.ObjectContext.ObjectStateManager.TryGetObjectStateEntry(entity, out stateEntry) CodeMethodInvokeExpression getObjectStateEntryCall = new CodeMethodInvokeExpression(objectStateMgrRef, "TryGetObjectStateEntry", entityArgRef, outEntityStateRef); // if (...TryGet()) CodeExpression tryGetTest = CodeGenUtilities.MakeEqual(typeof(bool), getObjectStateEntryCall, new CodePrimitiveExpression(false), codeGenContext.IsCSharp); // if (...TryGet..) { return EntityState.Detached; } CodeMethodReturnStatement returnDetached = new CodeMethodReturnStatement(detachedStateRef); CodeConditionStatement ifTryGet = new CodeConditionStatement(tryGetTest, returnDetached); method.Statements.Add(ifTryGet); // Return entityState.State; method.Statements.Add(new CodeMethodReturnStatement(new CodePropertyReferenceExpression(entityStateRef, "State"))); // CodeDom does not support specifying 'out' parameters at the method call site. // So convert the entire method into a snippet of text StringBuilder snippet = null; CodeDomProvider provider = codeGenContext.Provider; using (StringWriter snippetWriter = new StringWriter(System.Globalization.CultureInfo.CurrentCulture)) { provider.GenerateCodeFromMember(method, snippetWriter, codeGenContext.CodeGeneratorOptions); snippet = snippetWriter.GetStringBuilder(); } // Our convention above is that "_out_" will be replaced by the language-appropriate "out" parameter modifier. // In the case of VB, it is the default snippet.Replace("_out_", codeGenContext.IsCSharp ? "out " : string.Empty); // We need to indent the entire snippet 2 levels string indent = codeGenContext.CodeGeneratorOptions.IndentString; indent += indent; string snippetText = indent + snippet.ToString().Replace(Environment.NewLine, Environment.NewLine + indent).TrimEnd(' '); CodeSnippetTypeMember methodAsText = new CodeSnippetTypeMember(snippetText); return(methodAsText); }