-
Notifications
You must be signed in to change notification settings - Fork 0
/
WCFServiceInvoker.cs
84 lines (78 loc) · 3.13 KB
/
WCFServiceInvoker.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
using System;
using System.Collections.Generic;
using System.Configuration;
using System.ServiceModel;
using System.ServiceModel.Configuration;
namespace WCFUtils
{
/// <summary>
/// Adapted from Darin Dimitrov http://stackoverflow.com/questions/3200197/creating-wcf-channelfactoryt/3201001#3201001
/// </summary>
public class WCFServiceInvoker
{
private readonly ChannelFactoryManager _factoryManager;
private static readonly ClientSection _clientSection = ConfigurationManager.GetSection("system.serviceModel/client") as ClientSection;
public WCFServiceInvoker(ChannelFactoryManager factoryManager)
{
_factoryManager = factoryManager;
}
public TR InvokeService<T, TR>(Func<T, TR> invokeHandler) where T : class
{
var endpointNameAddressPair = GetEndpointNameAddressPair(typeof(T));
var arg = _factoryManager.CreateChannel<T>(endpointNameAddressPair.Key, endpointNameAddressPair.Value);
var communicationObject = (ICommunicationObject)arg;
try
{
return invokeHandler(arg);
}
finally
{
DoTheShutdownDance(communicationObject);
}
}
public void InvokeService<T>(Action<T> invokeHandler) where T : class
{
var endpointNameAddressPair = GetEndpointNameAddressPair(typeof(T));
var arg = _factoryManager.CreateChannel<T>(endpointNameAddressPair.Key, endpointNameAddressPair.Value);
var communicationObject = (ICommunicationObject)arg;
try
{
invokeHandler(arg);
}
finally
{
DoTheShutdownDance(communicationObject);
}
}
private static void DoTheShutdownDance(ICommunicationObject communicationObject)
{
try
{
if (communicationObject.State != CommunicationState.Faulted)
{
communicationObject.Close();
}
}
catch
{
communicationObject.Abort();
}
}
private KeyValuePair<string, string> GetEndpointNameAddressPair(Type serviceContractType)
{
var configException = new ConfigurationErrorsException(string.Format("No client endpoint found for type {0}. Please add the section <client><endpoint name=\"myservice\" address=\"http://address/\" binding=\"basicHttpBinding\" contract=\"{0}\"/></client> in the config file.", serviceContractType));
if (((_clientSection == null) || (_clientSection.Endpoints == null)) || (_clientSection.Endpoints.Count < 1))
{
throw configException;
}
foreach (ChannelEndpointElement element in _clientSection.Endpoints)
{
if (element.Contract == serviceContractType.ToString())
{
return new KeyValuePair<string, string>(element.Name, element.Address.AbsoluteUri);
}
}
throw configException;
}
}
}