如何使用
1、第一种方式比较简单,而且也是大家喜欢的,因为不需要任何配置文件就可解决,只需知道服务契约接口和服务地址就可以调用。
2、使用Invoke的方式,但是需要在调用客户端配置WCF,配置后在Invoke类里封装服务契约接口即可。
客户端调用DEMO
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
|
//第一种方式
string url = "http://localhost:3000/DoubleService.svc" ;
IDoubleService proxy = WcfInvokeFactory.CreateServiceByUrl<IDoubleService>(url);
int result = proxy.Add(1, 3);
//第二种方式<br><br>int result1 = WCFInvoke.Invoke(t => t.Add(1, 3));<br><br>
<system.serviceModel>
<behaviors>
<endpointBehaviors>
<behavior name= "NewBehavior" >
<dataContractSerializer maxItemsInObjectGraph= "65536000" />
</behavior>
</endpointBehaviors>
</behaviors>
<bindings>
<basicHttpBinding>
<binding name= "BasicHttpBinding_IDoubleService"
closeTimeout= "01:00:00"
openTimeout= "01:00:00"
sendTimeout= "01:00:00"
receiveTimeout= "01:00:00"
maxBufferSize= "2147483647"
maxBufferPoolSize= "524288"
maxReceivedMessageSize= "2147483647" >
<readerQuotas maxDepth= "128" maxStringContentLength= "2147483647" maxArrayLength= "16384" maxBytesPerRead= "4096" maxNameTableCharCount= "16384" />
</binding>
</basicHttpBinding>
<netMsmqBinding>
<binding name= "NetMsmqBinding_IAsyncSender" >
<security mode= "None" />
</binding>
</netMsmqBinding>
</bindings>
<client>
<endpoint address= "http://localhost:3000/DoubleService.svc"
binding= "basicHttpBinding"
bindingConfiguration= "BasicHttpBinding_IDoubleService"
contract= "DoubleStone.WebHost.IDoubleService"
name= "BasicHttpBinding_IDoubleService" />
</client>
</system.serviceModel>
|
第一种调用方式
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
|
public class WcfInvokeFactory
{
#region WCF服务工厂
public static T CreateServiceByUrl<T>( string url)
{
return CreateServiceByUrl<T>(url, "basicHttpBinding" );
}
public static T CreateServiceByUrl<T>( string url, string bing)
{
try
{
if ( string .IsNullOrEmpty(url)) throw new NotSupportedException( "This url is not Null or Empty!" );
EndpointAddress address = new EndpointAddress(url);
Binding binding = CreateBinding(bing);
ChannelFactory<T> factory = new ChannelFactory<T>(binding, address);
return factory.CreateChannel();
}
catch (Exception ex)
{
throw new Exception( "创建服务工厂出现异常." );
}
}
#endregion
#region 创建传输协议
/// <summary>
/// 创建传输协议
/// </summary>
/// <param name="binding">传输协议名称</param>
/// <returns></returns>
private static Binding CreateBinding( string binding)
{
Binding bindinginstance = null ;
if (binding.ToLower() == "basichttpbinding" )
{
BasicHttpBinding ws = new BasicHttpBinding();
ws.MaxBufferSize = 2147483647;
ws.MaxBufferPoolSize = 2147483647;
ws.MaxReceivedMessageSize = 2147483647;
ws.ReaderQuotas.MaxStringContentLength = 2147483647;
ws.CloseTimeout = new TimeSpan(0, 30, 0);
ws.OpenTimeout = new TimeSpan(0, 30, 0);
ws.ReceiveTimeout = new TimeSpan(0, 30, 0);
ws.SendTimeout = new TimeSpan(0, 30, 0);
bindinginstance = ws;
}
else if (binding.ToLower() == "nettcpbinding" )
{
NetTcpBinding ws = new NetTcpBinding();
ws.MaxReceivedMessageSize = 65535000;
ws.Security.Mode = SecurityMode.None;
bindinginstance = ws;
}
else if (binding.ToLower() == "wshttpbinding" )
{
WSHttpBinding ws = new WSHttpBinding(SecurityMode.None);
ws.MaxReceivedMessageSize = 65535000;
ws.Security.Message.ClientCredentialType = System.ServiceModel.MessageCredentialType.Windows;
ws.Security.Transport.ClientCredentialType = System.ServiceModel.HttpClientCredentialType.Windows;
bindinginstance = ws;
}
return bindinginstance;
}
#endregion
}
|
第二种调用方式
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
|
public class WCFInvoke
{
/// <summary>
/// 你需要调用的服务契约
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="func"></param>
/// <returns></returns>
public static T Invoke<T>(Func<IDoubleService, T> func)
{
IServiceInvoker serviceInvoker= new WCFServiceInvoker();
return serviceInvoker.InvokeService(func);
}
}
public interface IServiceInvoker
{
void InvokeService<T>(Action<T> invokeHandler) where T : class ;
TReslt InvokeService<T, TReslt>(Func<T, TReslt> invokeHandler) where T : class ;
}
public class WCFServiceInvoker:IServiceInvoker
{
private static readonly ChannelFactoryManager FactoryManager = new ChannelFactoryManager();
private static readonly ClientSection ClientSection =
ConfigurationManager.GetSection( "system.serviceModel/client" ) as ClientSection;
public void InvokeService<T>(Action<T> invokeHandler) where T : class
{
KeyValuePair< string , string > endpointNameAddressPair = GetEndpointNameAddressPair( typeof (T));
var arg = FactoryManager.CreateChannel<T>(endpointNameAddressPair.Key, endpointNameAddressPair.Value);
var obj2 = (ICommunicationObject)arg;
try
{
invokeHandler(arg);
}
finally
{
try
{
if (obj2.State != CommunicationState.Faulted)
{
obj2.Close();
}
}
catch
{
obj2.Abort();
}
}
}
public TReslt InvokeService<T, TReslt>(Func<T, TReslt> invokeHandler) where T : class
{
KeyValuePair< string , string > endpointNameAddressPair = GetEndpointNameAddressPair( typeof (T));
var arg = FactoryManager.CreateChannel<T>(endpointNameAddressPair.Key, endpointNameAddressPair.Value);
var obj2 = (ICommunicationObject)arg;
try
{
return invokeHandler(arg);
}
finally
{
try
{
if (obj2.State != CommunicationState.Closed || obj2.State != CommunicationState.Faulted)
{
obj2.Close();
}
}
catch
{
obj2.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;
}
}
|
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
|
public class ChannelFactoryManager : IDisposable
{
private static readonly Dictionary<Type, ChannelFactory> Factories = new Dictionary<Type, ChannelFactory>();
private static readonly object SyncRoot = new object ();
public void Dispose()
{
Dispose( true );
}
public virtual T CreateChannel<T>() where T : class
{
return CreateChannel<T>( "*" , null );
}
public virtual T CreateChannel<T>( string endpointConfigurationName) where T : class
{
return CreateChannel<T>(endpointConfigurationName, null );
}
public virtual T CreateChannel<T>( string endpointConfigurationName, string endpointAddress) where T : class
{
T local = GetFactory<T>(endpointConfigurationName, endpointAddress).CreateChannel();
((IClientChannel)local).Faulted += ChannelFaulted;
return local;
}
protected virtual ChannelFactory<T> GetFactory<T>( string endpointConfigurationName, string endpointAddress)
where T : class
{
lock (SyncRoot)
{
ChannelFactory factory;
if (!Factories.TryGetValue( typeof (T), out factory))
{
factory = CreateFactoryInstance<T>(endpointConfigurationName, endpointAddress);
Factories.Add( typeof (T), factory);
}
return (factory as ChannelFactory<T>);
}
}
private ChannelFactory CreateFactoryInstance<T>( string endpointConfigurationName, string endpointAddress)
{
ChannelFactory factory = null ;
factory = ! string .IsNullOrEmpty(endpointAddress) ? new ChannelFactory<T>(endpointConfigurationName, new EndpointAddress(endpointAddress)) : new ChannelFactory<T>(endpointConfigurationName);
factory.Faulted += FactoryFaulted;
factory.Open();
return factory;
}
private void ChannelFaulted( object sender, EventArgs e)
{
var channel = (IClientChannel)sender;
try
{
channel.Close();
}
catch
{
channel.Abort();
}
}
private void FactoryFaulted( object sender, EventArgs args)
{
var factory = (ChannelFactory)sender;
try
{
factory.Close();
}
catch
{
factory.Abort();
}
Type[] genericArguments = factory.GetType().GetGenericArguments();
if ((genericArguments.Length == 1))
{
Type key = genericArguments[0];
if (Factories.ContainsKey(key))
{
Factories.Remove(key);
}
}
}
protected virtual void Dispose( bool disposing)
{
if (disposing)
{
lock (SyncRoot)
{
foreach (Type type in Factories.Keys)
{
ChannelFactory factory = Factories[type];
try
{
factory.Close();
}
catch
{
factory.Abort();
}
}
Factories.Clear();
}
}
}
}
|
总结
第一种方式比较常见,第二种方式是我参考另外一个项目中的写法,其中的有一些细节我还没有搞明白,实现了这个功能后还需要再看看这部分代码,再消化消化。以上就是这篇文章的全部内容,希望能给大家带来一定的帮助,如果有疑问大家可以留言交流。
原文链接:http://www.cnblogs.com/sword-successful/p/4760376.html