/// <summary>
        /// Generates client proxy source code using the generator specified by <paramref name="codeGeneratorName"/>.
        /// </summary>
        /// <param name="options">The options to use for code generation.</param>
        /// <param name="parameters">The parameters required to create the <see cref="ISharedCodeService"/>.</param>
        /// <param name="loggingService">The service to use for logging.</param>
        /// <param name="codeGeneratorName">Optional generator name.  A <c>null</c> or empty value will select the default generator.</param>
        /// <returns>The generated source code or <c>null</c> if none was generated.</returns>
        internal string GenerateCode(ClientCodeGenerationOptions options, SharedCodeServiceParameters parameters, ILoggingService loggingService, string codeGeneratorName)
        {
            Debug.Assert(options != null, "options cannot be null");
            Debug.Assert(parameters != null, "parameters cannot be null");
            Debug.Assert(loggingService != null, "loggingService cannot be null");

            try
            {
                AppDomainUtilities.ConfigureAppDomain(options);
                LoadOpenRiaServicesServerAssembly(parameters, loggingService);

                using (SharedCodeService sharedCodeService = new SharedCodeService(parameters, loggingService))
                {
                    CodeGenerationHost host = new CodeGenerationHost(loggingService, sharedCodeService);
                    return(this.GenerateCode(host, options, parameters.ServerAssemblies, codeGeneratorName));
                }
            }
            catch (Exception ex)
            {
                // Fatal exceptions are never swallowed or processed
                if (ex.IsFatal())
                {
                    throw;
                }

                // Any exception from the code generator is caught and reported, otherwise it will
                // hit the MSBuild backstop and report failure of the custom build task.
                // It is acceptable to report this exception and "ignore" it because we
                // are running in a separate AppDomain which will be torn down immediately
                // after our return.
                loggingService.LogError(string.Format(CultureInfo.CurrentCulture,
                                                      Resource.ClientCodeGenDispatecher_Threw_Exception_Before_Generate,
                                                      ex.Message));
                loggingService.LogException(ex);
                return(null);
            }
        }
        /// <summary>
        /// Generates client proxy source code using the generator specified by <paramref name="codeGeneratorName"/>.
        /// </summary>
        /// <param name="options">The options to use for code generation.</param>
        /// <param name="parameters">The parameters required to create the <see cref="ISharedCodeService"/>.</param>
        /// <param name="loggingService">The service to use for logging.</param>
        /// <param name="codeGeneratorName">Optional generator name.  A <c>null</c> or empty value will select the default generator.</param>
        /// <returns>The generated source code or <c>null</c> if none was generated.</returns>
        internal string GenerateCode(ClientCodeGenerationOptions options, SharedCodeServiceParameters parameters, ILoggingService loggingService, string codeGeneratorName)
        {
            Debug.Assert(options != null, "options cannot be null");
            Debug.Assert(parameters != null, "parameters cannot be null");
            Debug.Assert(loggingService != null, "loggingService cannot be null");

            try
            {
                AppDomainUtilities.ConfigureAppDomain(options);
                LoadOpenRiaServicesServerAssembly(parameters, loggingService);

                using (SharedCodeService sharedCodeService = new SharedCodeService(parameters, loggingService))
                {
                    CodeGenerationHost host = new CodeGenerationHost(loggingService, sharedCodeService);
                    return this.GenerateCode(host, options, parameters.ServerAssemblies, codeGeneratorName);
                }
            }
            catch (Exception ex)
            {
                // Fatal exceptions are never swallowed or processed
                if (ex.IsFatal())
                {
                    throw;
                }

                // Any exception from the code generator is caught and reported, otherwise it will
                // hit the MSBuild backstop and report failure of the custom build task.
                // It is acceptable to report this exception and "ignore" it because we
                // are running in a separate AppDomain which will be torn down immediately
                // after our return.
                loggingService.LogError(string.Format(CultureInfo.CurrentCulture,
                                                Resource.ClientCodeGenDispatecher_Threw_Exception_Before_Generate,
                                                ex.Message));
                loggingService.LogException(ex);
                return null;
            }
        }