-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathProxyHelper.cs
More file actions
146 lines (126 loc) · 7.01 KB
/
Copy pathProxyHelper.cs
File metadata and controls
146 lines (126 loc) · 7.01 KB
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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
using System;
using System.Collections.Concurrent;
using System.Net;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Description;
using System.ServiceModel.Dispatcher;
namespace NetCoreStack.Wcf.Client
{
public class ProxyHelper
{
public static string DefaultEndpointBaseUrl { get; set; }
public static Type DefaultBindingType { get; set; }
public static string DefaultBindingConfigurationName { get; set; }
public static bool UseExtendedRealChannelFactory { get; set; }
public DefaultEndpointAddressResolver EndpointAddressResolver { get; set; }
public DefaultSurrogateBehavior DataContractSurrogateBehavior { get; set; }
public IClientMessageInspector ClientMessageInspectorBehavior { get; set; }
private static ConcurrentDictionary<Type, Lazy<ChannelFactory>> ChannelFactoryCache { get; set; }
public ProxyHelper()
{
ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
EndpointAddressResolver = new DefaultEndpointAddressResolver();
ClientMessageInspectorBehavior = new ClientMessageInspectorBehavior();
DataContractSurrogateBehavior = new DefaultSurrogateBehavior();
DefaultEndpointBaseUrl = ConfigurationSettingsManager.GetApplicationSetting("DefaultEndpointBaseUrl");
var bindingName = String.IsNullOrEmpty(ConfigurationSettingsManager.GetApplicationSetting("DefaultBindingType")) ? "BasicHttpBinding" : ConfigurationSettingsManager.GetApplicationSetting("DefaultBindingType");
DefaultBindingType = Type.GetType((bindingName == "CustomBinding" ? String.Format("System.ServiceModel.Channels.{0}, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089", bindingName) : String.Format("System.ServiceModel.{0}, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089", bindingName)));
DefaultBindingConfigurationName = String.IsNullOrEmpty(ConfigurationSettingsManager.GetApplicationSetting("DefaultBindingConfigurationName")) ? string.Empty : ConfigurationSettingsManager.GetApplicationSetting("DefaultBindingConfigurationName");
ChannelFactoryCache = new ConcurrentDictionary<Type, Lazy<ChannelFactory>>();
}
private ServiceEndpoint PrepareProxyAndGetServiceEndpoint(Type contractType)
{
var contractFullNameWithoutAssembly = String.Format("{0}.{1}", contractType.Namespace, contractType.Name);
var endpointSetting = ConfigurationSettingsManager.GetServiceEndPointSetting(contractFullNameWithoutAssembly);
if (endpointSetting == null)
{
string assemblyName = contractType.Assembly.GetName().Name;
endpointSetting = ConfigurationSettingsManager.GetServiceEndPointSetting(assemblyName);
}
Type bindingType = DefaultBindingType;
string bindingConfigurationName = DefaultBindingConfigurationName;
string endpointBaseAddress = DefaultEndpointBaseUrl;
if (endpointSetting != null)
{
if (!string.IsNullOrEmpty(endpointSetting.Binding))
{
bindingType = Type.GetType((endpointSetting.Binding == "CustomBinding"
? String.Format(
"System.ServiceModel.Channels.{0}, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",
endpointSetting.Binding)
: String.Format(
"System.ServiceModel.{0}, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",
endpointSetting.Binding)));
}
if (!string.IsNullOrEmpty(endpointSetting.BindingConfiguration))
{
bindingConfigurationName = endpointSetting.BindingConfiguration;
}
if (!string.IsNullOrEmpty(endpointSetting.BaseAddress))
{
endpointBaseAddress = endpointSetting.BaseAddress;
}
}
var binding = string.IsNullOrEmpty(bindingConfigurationName)
? (Binding)Activator.CreateInstance(bindingType)
: (Binding)Activator.CreateInstance(bindingType, bindingConfigurationName);
var endPoint = new ServiceEndpoint(ContractDescription.GetContract(contractType),
binding,
new EndpointAddress(EndpointAddressResolver.Resolve(contractType, endpointBaseAddress)));
if (DataContractSurrogateBehavior != null)
{
foreach (var operation in endPoint.Contract.Operations)
{
operation.OperationBehaviors.Add(DataContractSurrogateBehavior);
}
}
if (ClientMessageInspectorBehavior != null)
{
endPoint.EndpointBehaviors.Add((IEndpointBehavior)ClientMessageInspectorBehavior);
}
return endPoint;
}
private dynamic GetChannelFactoryFromCache(Type contractType, Lazy<ChannelFactory> cf)
{
dynamic dcf = cf.Value;
if (((ChannelFactory)dcf).State == CommunicationState.Faulted)
{
if (ChannelFactoryCache.TryRemove(contractType, out cf))
{
var serviceEndPoint = PrepareProxyAndGetServiceEndpoint(contractType);
dcf = ChannelFactoryCache.GetOrAdd(contractType,
new Lazy<ChannelFactory>(() =>
(ChannelFactory)Activator.CreateInstance(typeof(ChannelFactory<>)
.MakeGenericType(contractType), serviceEndPoint))).Value;
}
}
return dcf.CreateChannel();
}
public TContract CreateProxy<TContract>() where TContract : class
{
return (TContract)CreateProxy(typeof(TContract));
}
public object CreateProxy(Type contractType)
{
// cache exist check
if (ChannelFactoryCache.ContainsKey(contractType))
{
Lazy<ChannelFactory> cf;
if (ChannelFactoryCache.TryGetValue(contractType, out cf))
{
if (cf != null)
{
return GetChannelFactoryFromCache(contractType, cf);
}
}
}
ServiceEndpoint endPoint = PrepareProxyAndGetServiceEndpoint(contractType);
dynamic channelFactory;
channelFactory = ChannelFactoryCache.GetOrAdd(contractType,
new Lazy<ChannelFactory>(() =>
(ChannelFactory)Activator.CreateInstance(typeof(ChannelFactory<>).MakeGenericType(contractType), endPoint))).Value;
return channelFactory.CreateChannel();
}
}
}