Thinktecture.Tools.Web.Services.CodeGeneration.ServiceTypeGenerator.CreateServiceType C# (CSharp) Method

CreateServiceType() private method

private CreateServiceType ( ) : void
return void
        private void CreateServiceType()
        {
            // We can create the service type(s) only if we have one or more service
            // contract.
            if (code.ServiceContracts.Count > 0)
            {
                // Take a reference to the first ServiceContract available.
                // IMPORTANT!:(Currently we only support single service type)
                // May be want to support multiple service contracts in the next version.
                CodeTypeExtension srvContract = code.ServiceContracts[0];
                // Notify if srvContract is null. This would mean that we have constructed a bad
                // GeneratedCode instance from our CodeFactory.
                Debug.Assert(srvContract != null, "Generated service contract could not be null.");

                // Construct the service type name by removing the leading "I" character from
                // the service contract name that was added for generation of the interface.
                string srvTypeName = srvContract.ExtendedObject.Name.Substring(1);

                // Create a new instance of CodeTypeDeclaration type representing the service type.
                CodeTypeDeclaration srvType = new CodeTypeDeclaration(srvTypeName);

                // Also wrap the CodeTypeDeclaration in an extension.
                CodeTypeExtension typeExt = new CodeTypeExtension(srvType);

                // This class.
                srvType.IsClass = true;

                switch (options.MethodImplementation)
                {
                    case MethodImplementation.PartialClassMethodCalls:
                        // The service type is partial so that the implementation methods can be written in separate file.
                        srvType.IsPartial = true;
                        break;
                    case MethodImplementation.AbstractMethods:
                        // The service type is abstract so that the operation methods can be made abstract.
                        srvType.TypeAttributes |= TypeAttributes.Abstract;
                        break;
                }

                // And this implements the service contract interface.
                if (code.CodeLanguauge == CodeLanguage.VisualBasic)
                {
                    srvType.Members.Add(new CodeSnippetTypeMember("Implements " + srvContract.ExtendedObject.Name));
                }
                else
                {
                    srvType.BaseTypes.Add(new CodeTypeReference(srvContract.ExtendedObject.Name));
                }

                // Now itterate the srvContractObject.Members and add each and every method in
                // the service contract type to the new type being created.
                foreach (CodeTypeMemberExtension methodExtension in srvContract.Methods)
                {
                    // Get a referece to the actual CodeMemberMethod object extended
                    // by ext.
                    CodeMemberMethod method = methodExtension.ExtendedObject as CodeMemberMethod;

                    // Create a new CodeMemeberMethod and copy the attributes.
                    CodeMemberMethod newMethod = new CodeMemberMethod();
                    newMethod.Name = method.Name;

                    // Implemented method has to be public.
                    newMethod.Attributes = MemberAttributes.Public;

                    // Notify that this member is implementing a method in the service contract.
                    if (code.CodeLanguauge == CodeLanguage.VisualBasic)
                    {
                        newMethod.ImplementationTypes.Add(new CodeTypeReference(srvContract.ExtendedObject.Name));
                    }
                    else
                    {
                        newMethod.ImplementationTypes.Add(srvType.BaseTypes[0]);
                    }

                    // Add all parametes to the newly created method.
                    foreach (CodeParameterDeclarationExpression cpde in method.Parameters)
                    {
                        newMethod.Parameters.Add(cpde);
                    }

                    // Set the return type.
                    newMethod.ReturnType = method.ReturnType;

                    switch (options.MethodImplementation)
                    {
                        case MethodImplementation.PartialClassMethodCalls:
                            {
                                // Gather the parameters from the operation to pass into the implementation method.
                                IEnumerable<CodeArgumentReferenceExpression> parameters = newMethod.Parameters
                                    .OfType<CodeParameterDeclarationExpression>()
                                    .Select(p => new CodeArgumentReferenceExpression(p.Name));

                                // Create an expression to invoke the implementation method.
                                CodeMethodInvokeExpression methodInvocation = new CodeMethodInvokeExpression(null, newMethod.Name + "Implementation", parameters.ToArray());

                                // Check if the method has a return type.
                                if (newMethod.ReturnType.BaseType != "System.Void")
                                {
                                    // Make sure the call to the implementation method is returned.
                                    CodeMethodReturnStatement returnStatement = new CodeMethodReturnStatement(methodInvocation);
                                    newMethod.Statements.Add(returnStatement);
                                }
                                else
                                {
                                    // Add the call to the implementation method without a return.
                                    newMethod.Statements.Add(methodInvocation);
                                }
                            }
                            break;
                        case MethodImplementation.NotImplementedException:
                            {
                                // Create a new code statement to throw NotImplementedExcption.
                                CodeThrowExceptionStatement niex = new CodeThrowExceptionStatement(
                                    new CodeObjectCreateExpression(
                                        new CodeTypeReference(typeof(NotImplementedException)), new CodeExpression[] { })
                                    );

                                // Add it to the statements collection in the new method.
                                newMethod.Statements.Add(niex);
                            }
                            break;
                        case MethodImplementation.AbstractMethods:
                            {
                                // No statement is required for the abstract methods.
                                newMethod.Attributes |= MemberAttributes.Abstract;
                                break;
                            }
                    }

                    // Wrap the CodeMemberMethod in an extension. This could be useful for other extensions.
                    CodeTypeMemberExtension newMethodExt = new CodeTypeMemberExtension(newMethod, typeExt);
                    srvType.Members.Add(newMethodExt);
                }

                // Add the ServiceBehaviorAttribute attribute.
                CodeAttributeDeclaration serviceBehaviorAttribute = new CodeAttributeDeclaration(
                    new CodeTypeReference(typeof(ServiceBehaviorAttribute)));

                if (!string.IsNullOrEmpty(options.InstanceContextMode))
                {
                    CodeTypeReferenceExpression instanceContextModeEnum = new CodeTypeReferenceExpression(typeof(InstanceContextMode));
                    CodeFieldReferenceExpression instanceContextModeValue = new CodeFieldReferenceExpression(instanceContextModeEnum, options.InstanceContextMode);
                    CodeAttributeArgument instanceContextModeArgument = new CodeAttributeArgument("InstanceContextMode", instanceContextModeValue);
                    serviceBehaviorAttribute.Arguments.Add(instanceContextModeArgument);
                }

                if (!string.IsNullOrEmpty(options.ConcurrencyMode))
                {
                    CodeTypeReferenceExpression concurrencyModeEnum = new CodeTypeReferenceExpression(typeof(ConcurrencyMode));
                    CodeFieldReferenceExpression concurrencyModeValue = new CodeFieldReferenceExpression(concurrencyModeEnum, options.ConcurrencyMode);
                    CodeAttributeArgument concurrencyModeArgument = new CodeAttributeArgument("ConcurrencyMode", concurrencyModeValue);
                    serviceBehaviorAttribute.Arguments.Add(concurrencyModeArgument);
                }

                if (!options.UseSynchronizationContext)
                {
                    CodeAttributeArgument useSynchronizationContextAttribute = new CodeAttributeArgument("UseSynchronizationContext", new CodePrimitiveExpression(false));
                    serviceBehaviorAttribute.Arguments.Add(useSynchronizationContextAttribute);
                }

                typeExt.AddAttribute(serviceBehaviorAttribute);

                this.serviceTypeName = srvType.Name;
                // Finally add the newly created type to the code being generated.
                code.ServiceTypes.Add(typeExt);
            }
        }
ServiceTypeGenerator