#region License Information /* HeuristicLab * Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL) * * This file is part of HeuristicLab. * * HeuristicLab is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * HeuristicLab is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with HeuristicLab. If not, see . */ #endregion using System; using System.ServiceModel; using HeuristicLab.Clients.Common.Properties; using System.ServiceModel.Description; using System.Collections; using System.Collections.Generic; using HeuristicLab.Common; namespace HeuristicLab.Clients.Common { public static class ClientFactory { public static T CreateClient() where T : ClientBase, I where I : class { return CreateClient(null, null); } public static T CreateClient(string endpointConfigurationName) where T : ClientBase, I where I : class { return CreateClient(endpointConfigurationName, null); } public static T CreateClient(string endpointConfigurationName, string remoteAddress) where T : ClientBase, I where I : class { return CreateClient(endpointConfigurationName, remoteAddress, Settings.Default.UserName, Settings.Default.Password); } public static T CreateClient(string endpointConfigurationName, string remoteAddress, string userName, string password) where T : ClientBase, I where I : class { T client; if (string.IsNullOrEmpty(endpointConfigurationName)) { client = Activator.CreateInstance(); } else { client = (T)Activator.CreateInstance(typeof(T), endpointConfigurationName); } if (!string.IsNullOrEmpty(remoteAddress)) { SetEndpointAddress(client.Endpoint, remoteAddress); } client.ClientCredentials.UserName.UserName = userName; client.ClientCredentials.UserName.Password = password; client.ClientCredentials.ServiceCertificate.Authentication.CertificateValidationMode = System.ServiceModel.Security.X509CertificateValidationMode.None; return client; } public static Disposable CreateClient(string endpointConfigurationName) where I : class { return CreateClient(endpointConfigurationName, null); } public static Disposable CreateClient(string endpointConfigurationName, string remoteAddress) where I : class { return CreateClient(endpointConfigurationName, remoteAddress, Settings.Default.UserName, Settings.Default.Password); } public static Disposable CreateClient(string endpointConfigurationName, string remoteAddress, string userName, string password) where I : class { ChannelFactory factory = GetChannelFactory(endpointConfigurationName, userName, password); if (!string.IsNullOrEmpty(remoteAddress)) { SetEndpointAddress(factory.Endpoint, remoteAddress); } Disposable disposable = new Disposable(factory.CreateChannel()); disposable.OnDisposing += new EventHandler>(disposable_OnDisposing); return disposable; } private static void disposable_OnDisposing(object sender, EventArgs e) { DisposeCommunicationObject((ICommunicationObject)e.Value); ((Disposable)sender).OnDisposing -= new EventHandler>(disposable_OnDisposing); } private static IDictionary channelFactoryCache = new Dictionary(); private static ChannelFactory GetChannelFactory(string endpointConfigurationName, string userName, string password) where I : class { ChannelProperties key = new ChannelProperties(typeof(I), endpointConfigurationName, userName, password); if (!channelFactoryCache.ContainsKey(key)) { channelFactoryCache.Add(key, new ChannelFactory(endpointConfigurationName)); channelFactoryCache[key].Credentials.UserName.UserName = userName; channelFactoryCache[key].Credentials.UserName.Password = password; channelFactoryCache[key].Credentials.ServiceCertificate.Authentication.CertificateValidationMode = System.ServiceModel.Security.X509CertificateValidationMode.None; } return (ChannelFactory)channelFactoryCache[key]; } public static void DisposeCommunicationObject(ICommunicationObject obj) { if (obj != null) { if (obj.State != CommunicationState.Faulted && obj.State != CommunicationState.Closed) { try { obj.Close(); } catch { obj.Abort(); } } else { obj.Abort(); } } } /// /// This method changes the endpoint-address while preserving the identity-certificate defined in the config file /// private static void SetEndpointAddress(ServiceEndpoint endpoint, string remoteAddress) { EndpointAddressBuilder endpointAddressbuilder = new EndpointAddressBuilder(endpoint.Address); UriBuilder uriBuilder = new UriBuilder(endpointAddressbuilder.Uri); uriBuilder.Host = remoteAddress; endpointAddressbuilder.Uri = uriBuilder.Uri; endpoint.Address = endpointAddressbuilder.ToEndpointAddress(); } } internal struct ChannelProperties { public Type type; public string endpointConfigurationName; public string userName; public string password; public ChannelProperties(Type type, string endpointConfigurationName, string userName, string password) { this.type = type; this.endpointConfigurationName = endpointConfigurationName; this.userName = userName; this.password = password; } } }