Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HeuristicLab.Hive/sources/HeuristicLab.Hive/HeuristicLab.Hive.Contracts/3.3/WcfServicePool.cs @ 4550

Last change on this file since 4550 was 4424, checked in by cneumuel, 14 years ago
  • Added and updated License Information in every file
  • Sort and remove usings in every file
  • Deleted obsolete DataAccess.ADOHelper
  • Deleted some obsolete files
File size: 5.2 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21
22using System;
23using System.ServiceModel;
24using HeuristicLab.Common;
25using HeuristicLab.Tracing;
26
27namespace HeuristicLab.Hive.Contracts {
28  public class WcfServicePool<T> {
29    private static object locker = new object();
30
31    private string hostAddress;
32    public string HostAddress {
33      get { return hostAddress; }
34      set {
35        if (hostAddress != value) {
36          hostAddress = value;
37          this.factory = null;
38        }
39      }
40    }
41
42    private string endpointName;
43
44    private string username;
45    public string Username {
46      get { return username; }
47      set {
48        if(username != value) {
49          username = value;
50          this.factory = null;
51        }
52      }
53    }
54
55    private string password;
56    public string Password {
57      set {
58        if (password != value) {
59          password = value;
60          this.factory = null;
61        }
62      }
63    }
64
65    private ChannelFactory<T> factory = null;
66    private Disposable<T> disposableService = null;
67    private int requestCount = 0;
68
69    public WcfServicePool(string hostAddress, string username, string password, string endpointName) {
70      this.hostAddress = hostAddress;
71      this.username = username;
72      this.password = password;
73      this.endpointName = endpointName;
74    }
75
76    private T CreateFacade(string endpointName) {
77      lock (locker) {
78        try {
79          return CreateChannel(endpointName);
80        }
81        catch (EndpointNotFoundException ex) {
82          OnExceptionOccured(ex);
83        }
84        return default(T);
85      }
86    }
87
88    protected virtual T CreateChannel(string endpointName) {
89      if (factory == null) {
90        factory = new ChannelFactory<T>(endpointName);
91        WcfSettings.SetEndpointAddress(factory.Endpoint, hostAddress);
92
93        factory.Credentials.UserName.UserName = username;
94        factory.Credentials.UserName.Password = password;
95      }
96     
97      return factory.CreateChannel();
98    }
99
100    public Disposable<T> GetService() {
101      lock (locker) {
102        requestCount++;
103        Logger.Debug("Request for ServiceProxy (count: " + requestCount + ")");
104        if (disposableService != null) {
105          if (GetServiceState() == CommunicationState.Faulted) {
106            DisposeService();
107          }
108        }
109        if (disposableService == null) {
110          disposableService = new Disposable<T>(CreateFacade(this.endpointName));
111          RegisterServiceEvents();
112        }       
113        return disposableService;
114      }
115    }
116
117    private void RegisterServiceEvents() {
118      disposableService.OnDisposing += new EventHandler(disposableService_OnDisposing);
119      ((ICommunicationObject)disposableService.Obj).Faulted += new EventHandler(WcfServicePool_Faulted);
120    }
121
122    private void DeregisterServiceEvents() {
123      disposableService.OnDisposing -= new EventHandler(disposableService_OnDisposing);
124      ((ICommunicationObject)disposableService.Obj).Faulted -= new EventHandler(WcfServicePool_Faulted);
125    }
126
127    private CommunicationState GetServiceState() {
128      return ((ICommunicationObject)disposableService.Obj).State;
129    }
130
131    void WcfServicePool_Faulted(object sender, EventArgs e) {
132      OnExceptionOccured(new CommunicationException(e.ToString()));
133    }
134
135    private void disposableService_OnDisposing(object sender, EventArgs e) {
136      DisposeService();
137    }
138
139    public void DisposeService() {
140      lock (locker) {
141        requestCount--;
142        Logger.Debug("Disposing ServiceProxy (count: " + requestCount + ")");
143        if (requestCount == 0) {
144          try {
145            DeregisterServiceEvents();
146            WcfSettings.DisposeWcfClient((ICommunicationObject)disposableService.Obj);
147          }
148          catch (Exception e) {
149            OnExceptionOccured(e);
150          }
151          finally {
152            disposableService = null;
153          }
154        } else if (requestCount < 0) {
155          throw new WcfServicePoolException("requestCount cannot be less than 0.");
156        }
157      }
158    }
159
160    public event EventHandler<EventArgs<Exception>> ExceptionOccured;
161    private void OnExceptionOccured(Exception e) {
162      lock (locker) {
163        var handler = ExceptionOccured;
164        if (handler != null) handler(this, new EventArgs<Exception>(e));
165      }
166    }
167  }
168}
Note: See TracBrowser for help on using the repository browser.