问题描述
有关WCF客户端,我有一个 IServiceProxyFactory
界面来设置凭据。
公共接口IServiceProxyFactory< T>
{$ B $(B T)GetServiceProxy();
}
公共类ServiceProxy1:IServiceProxyFactory< ServiceClient1>
{
公共ServiceClient1 GetServiceProxy()
{
VAR的客户=新ServiceClient1();
//组凭据这里
返回客户端;
}
}
公共类ServiceProxy2:IServiceProxyFactory< ServiceClient2> {
// ...
}
从问题的和我创建了一个帮手如下:
公共静态类服务< TProxy,TClient>
式TProxy:IServiceProxyFactory< TClient>中新()
式TClient:ICommunicationObject
{
公共静态IServiceProxyFactory< TClient>代理=新TProxy();
公共静态无效使用(动作< TClient>码块)
{
TClient客户端=默认(TClient);
BOOL成功= FALSE;
试
{
客户端= proxy.GetServiceProxy();
码块(客户端);
((ICommunicationObject)客户端).Close();
成功= TRUE;
}
终于
{
如果
{
((ICommunicationObject)客户端).Abort()(成功!);
}
}
}
}
和我使用助手为:
服务与LT; ServiceProxy1,ServiceClient1>。用(SVC => svc.Method());
问:
-
有没有一种方法,我可以摆脱
TClient
或TProxy
(更新中)类型,这样我可以调用使用:服务与LT; ServiceProxy1>。用(SVC => SVC 。方法());
或(更新)
服务与LT; ServiceClient1>。用(SVC => svc.Method());
-
有没有更好的办法,而不是使用
ICommunicationObject
为关闭()
和中止()
?
我通过合并来实现它 ServiceProxy1
类到 ServiceClient1
使用 ServiceClient1:IServiceProxyFactory< ServiceClient1>
诱骗
公共接口IServiceProxyFactory< T>
{
//可以如setCredentials一个更好的名字()$ B $(B T)GetServiceProxy();
}
//摆脱ServiceProxy1类
的公共部分类ServiceClient1:IServiceProxyFactory< ServiceClient1>
{
公共ServiceClient1 GetServiceProxy()
{
VAR的客户=这一点;
//组凭据这里
//client.ClientCredentials =;
返回客户端;
}
}
公共部分类ServiceClient2:IServiceProxyFactory< ServiceClient2> {...}
公共静态类ServiceMod< TClient>
式TClient:类,ICommunicationObject,IServiceProxyFactory< TClient>中新()
{
公共静态TReturn使用< TReturn>(Func键< TClient,TReturn>码块)
{
TClient客户端=默认(TClient);
BOOL成功= FALSE;
试
{
客户端=新TClient()GetServiceProxy()。
TReturn结果=码块(客户端);
client.Close();
成功= TRUE;
返回结果;
}
终于
{
如果
{
client.Abort()(成功!);
}
}
}
}
和现在我可以这样做:
服务与LT; ServiceClient1>。用(SVC => svc.Method());
For WCF clients, I have a IServiceProxyFactory
interface to set credentials.
public interface IServiceProxyFactory<T>
{
T GetServiceProxy();
}
public class ServiceProxy1 : IServiceProxyFactory<ServiceClient1>
{
public ServiceClient1 GetServiceProxy()
{
var client = new ServiceClient1();
// set credentials here
return client;
}
}
public class ServiceProxy2 : IServiceProxyFactory<ServiceClient2> {
// ...
}
From the question What is the best workaround for the WCF client `using` block issue?, and I created a helper as follows:
public static class Service<TProxy, TClient>
where TProxy : IServiceProxyFactory<TClient>, new()
where TClient : ICommunicationObject
{
public static IServiceProxyFactory<TClient> proxy = new TProxy();
public static void Use(Action<TClient> codeBlock)
{
TClient client = default(TClient);
bool success = false;
try
{
client = proxy.GetServiceProxy();
codeBlock(client);
((ICommunicationObject)client).Close();
success = true;
}
finally
{
if (!success)
{
((ICommunicationObject)client).Abort();
}
}
}
}
And I use the helper as:
Service<ServiceProxy1, ServiceClient1>.Use(svc => svc.Method());
Question:
Is there a way where I can get rid of the
TClient
orTProxy
(updated) type so that I can call using:Service<ServiceProxy1>.Use(svc => svc.Method());
OR (updated)
Service<ServiceClient1>.Use(svc => svc.Method());
Is there a better way than to use
ICommunicationObject
forClose()
andAbort()
?
I achieved it by merging ServiceProxy1
class into ServiceClient1
by using ServiceClient1 : IServiceProxyFactory<ServiceClient1>
trick.
public interface IServiceProxyFactory<T>
{
// can have a better name like SetCredentials()
T GetServiceProxy();
}
// Got rid of ServiceProxy1 class
public partial class ServiceClient1 : IServiceProxyFactory<ServiceClient1>
{
public ServiceClient1 GetServiceProxy()
{
var client = this;
// set credentials here
//client.ClientCredentials = "";
return client;
}
}
public partial class ServiceClient2 : IServiceProxyFactory<ServiceClient2> { ... }
public static class ServiceMod<TClient>
where TClient : class, ICommunicationObject, IServiceProxyFactory<TClient>, new()
{
public static TReturn Use<TReturn>(Func<TClient, TReturn> codeBlock)
{
TClient client = default(TClient);
bool success = false;
try
{
client = new TClient().GetServiceProxy();
TReturn result = codeBlock(client);
client.Close();
success = true;
return result;
}
finally
{
if (!success)
{
client.Abort();
}
}
}
}
And now I can do:
Service<ServiceClient1>.Use(svc => svc.Method());
这篇关于是否有可能在服务类摆脱TClient泛型类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!