public void GetProxyAssembly_Returns_WebServiceProxyAssembly()
        {
            // Arrange.
            const int ServiceId = 111;
            const string EndpointsConfiguration = "Test Endpoints";

            lock (SyncRoot)
            {
                var processDal = Mock.Create<IProcessDal>(Behavior.Loose);
                var proxyGenerator = Mock.Create<IWebServiceProxyGenerator>(Behavior.Loose);

                WebServiceProxyAssemblyManager.ClearCache();

                var proxyManager = new WebServiceProxyAssemblyManager { ProcessDal = processDal, ServiceProxyGenerator = proxyGenerator };

                var code = new WebServiceClientCodeDto { EndpointsConfiguration = EndpointsConfiguration };
                Mock.Arrange(() => processDal.GetWebServiceClientCode(ServiceId)).Returns(code);

                var assembly = typeof(WebServiceProxyAssemblyManagerTests).Assembly;
                Mock.Arrange(() => proxyGenerator.GenerateAssembly(code)).Returns(assembly);

                // Act.
                var proxyAssembly = proxyManager.GetProxyAssembly(ServiceId);
                var cachedAssembly = proxyManager.GetProxyAssembly(ServiceId);

                // Assert.
                Assert.IsNotNull(proxyAssembly);
                Assert.AreSame(assembly, proxyAssembly.Assembly);
                Assert.AreEqual(EndpointsConfiguration, proxyAssembly.EndpointConfiguration);
            
                Assert.AreSame(proxyAssembly, cachedAssembly);
            }
        }
        /// <summary>
        /// Generates the assembly.
        /// </summary>
        /// <param name="code">The code.</param>
        /// <returns>Assembly.</returns>
        public Assembly GenerateAssembly(WebServiceClientCodeDto code)
        {
            var tempDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
            Directory.CreateDirectory(tempDirectory);

            var fileName = Path.Combine(tempDirectory, "sp-" + code.ServiceGuid + ".dll");

            BuildAssembly(fileName, code.Code);

            var assembly = Assembly.Load(File.ReadAllBytes(fileName));

            Directory.Delete(tempDirectory, true);

            return assembly;
        }
        /// <summary>
        /// Generates the code.
        /// </summary>
        /// <param name="serviceDescription">The service description.</param>
        /// <returns>WebServiceClientCodeDto.</returns>
        /// <exception cref="VeyronException">Service endpoints not found.</exception>
        public WebServiceClientCodeDto GenerateCode(WebServiceDescription serviceDescription)
        {
            var result = new WebServiceClientCodeDto { ServiceId = serviceDescription.Id, ServiceGuid = serviceDescription.Guid };

            using (var codeProvider = new CSharpCodeProvider())
            {
                var metadataSections = new List<MetadataSection>();
                metadataSections.AddRange(serviceDescription.XmlSchemas.Select(MetadataSection.CreateFromSchema));
                metadataSections.AddRange(serviceDescription.ServiceDescriptions.Select(MetadataSection.CreateFromServiceDescription));

                var @namespace = string.Format("sp_{0}", serviceDescription.Guid.ToString().Replace('-', '_'));
                var codeUnit = new CodeCompileUnit();

                var importer = new WsdlImporter(new MetadataSet(metadataSections));
                
                AddStateForXmlSerializerImport(importer, codeUnit, codeProvider, @namespace);
                AddStateForFaultSerializerImport(importer);
                RemoveDataContractSerializerExtension(importer);

                var endpoints = importer.ImportAllEndpoints();

                if (endpoints.Count == 0)
                {
                    if (importer.Errors.Any(e => !e.IsWarning))
                        throw new AggregateException("Service description import failed.", importer.Errors.Select(e => new Exception(e.Message)));

                    throw new VeyronException("Service endpoints not found.");
                }

                var endpoint = endpoints[0];

                var configDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());

                Directory.CreateDirectory(configDirectory);
                var configPath = Path.Combine(configDirectory, "endpoints.config");
                File.WriteAllText(configPath, EmptyConfiguration, Encoding.UTF8);

                var fileMap = new ExeConfigurationFileMap { ExeConfigFilename = configPath };
                var config = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);

                var contractGenerator = new ServiceContractGenerator(codeUnit, config);
                contractGenerator.NamespaceMappings.Add("*", @namespace);
                contractGenerator.Options = ServiceContractGenerationOptions.ClientClass | ServiceContractGenerationOptions.TypedMessages;

                contractGenerator.GenerateServiceContractType(endpoint.Contract);
                ChannelEndpointElement endpointElement;
                contractGenerator.GenerateServiceEndpoint(endpoint, out endpointElement);

                config.Save();
                result.EndpointsConfiguration = File.ReadAllText(configPath);

                Directory.Delete(configDirectory, true);

                using (var stringWriter = new StringWriter())
                {
                    var options = new CodeGeneratorOptions { BracingStyle = "C" };
                    codeProvider.GenerateCodeFromCompileUnit(codeUnit, stringWriter, options);
                    stringWriter.Flush();

                    result.Code = stringWriter.ToString();

                    return result;
                }
            }
        }