是否有可能在Service类中去掉TClient泛型类型?
本文关键字:TClient 泛型类型 有可能 Service 是否 | 更新日期: 2023-09-27 18:04:54
对于WCF客户机,我有一个IServiceProxyFactory
接口来设置凭据。
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> {
// ...
}
从问题是什么是WCF客户端'使用'块问题的最佳解决方案?,我创建了一个助手,如下所示:
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();
}
}
}
}
和我使用的帮助:
Service<ServiceProxy1, ServiceClient1>.Use(svc => svc.Method());
问题:
是否有一种方法,我可以摆脱
TClient
或TProxy
(更新)类型,以便我可以使用:Service<ServiceProxy1>.Use(svc => svc.Method());
或(更新)
Service<ServiceClient1>.Use(svc => svc.Method());
是否有比
Close()
和Abort()
使用ICommunicationObject
更好的方法?
-
代码
partial class TestClass { public static void TestMethod() { Service<ServiceProxy1>.Use(svc => svc.Method()); Service<ServiceProxy1>.Use(svc => svc.Method()); Service<ServiceProxy1>.Use(svc => svc.Method()); Service<ServiceProxy2>.Use(svc => svc.Method()); } } public partial interface IServiceProxyFactory<T> { T GetServiceProxy(); } public partial class Service<T> where T: ServiceProxy, new() { public static void Use(Action<T> codeBlock) { using(var client=ServiceProxy.GetServiceProxy<T>().GetServiceProxy() as T) try { codeBlock(client); } catch { throw; } } } public abstract partial class ServiceProxy: CommunicationObject, IDisposable { public static T GetServiceProxy<T>() where T: ServiceProxy, new() { var proxy=m_List.FirstOrDefault(x => typeof(T).Equals(x.GetType())) as T; if(null==proxy) { proxy=new T(); m_List.Add(proxy); } return proxy; } public abstract ServiceProxy GetServiceProxy(); public abstract void Method(); protected virtual void Dispose(bool disposing) { lock(ThisLock) if(!this.IsDisposed&&disposing) { this.Close(); if(!this.IsDisposed) this.Abort(); } } public void Dispose() { this.Dispose(true); GC.SuppressFinalize(this); } ~ServiceProxy() { this.Dispose(false); } static List<ServiceProxy> m_List=new List<ServiceProxy>(); } public partial class ServiceProxy1: ServiceProxy { protected override IAsyncResult OnBeginClose( TimeSpan timeout, AsyncCallback callback, object state ) { throw new NotImplementedException(); } protected override IAsyncResult OnBeginOpen( TimeSpan timeout, AsyncCallback callback, object state ) { throw new NotImplementedException(); } protected override void OnAbort() { } protected override void OnEndClose(IAsyncResult result) { } protected override void OnEndOpen(IAsyncResult result) { } protected override void OnClose(TimeSpan timeout) { } protected override void OnOpen(TimeSpan timeout) { } protected override TimeSpan DefaultCloseTimeout { get { return TimeSpan.Zero; } } protected override TimeSpan DefaultOpenTimeout { get { return TimeSpan.Zero; } } public override ServiceProxy GetServiceProxy() { var client=new ServiceProxy1(); // set credentials here return client; } public override void Method() { } } public partial class ServiceProxy2: ServiceProxy1 { public override ServiceProxy GetServiceProxy() { var client=new ServiceProxy2(); // set credentials here return client; } }
值得一提的是:
-
lock
可以安全地重新输入 -
我不可能对从
T
到任何Generic<T>
类型的反向推理进行完全相同的声明,例如从ServiseClient
到ServiceProxy<ServiceClient>
。 -
根据2,
ServiceProxy
和ServiceClient
在代码中是一样的,所以没有ServiceClient
。 -
ServiceProxy
本身是抽象。对于ServiceClient
需要转换为ICommunicationObject
的要求,为方便起见,按3 +,ServiceProxy
由CommunicationObject
衍生而来;然后对于有比…更好的方法吗?的东西,它实现了IDisposible
-
对于继承
ServiceProxy
的具体类的静态实例,每个实例只有一个实例,并存储在m_List
中,调用GetServiceProxy<T>()
的静态泛型版本只是获取它们。这个看起来更像是轻量级的图案。 -
根据5,接口
IServiceProxyFactory<T>
根本没有使用,只是把它放在那里看,感觉很开心。 -
GetServiceProxy()
的实例版本保持了原来的用法,但是具体类需要覆盖它。 -
在
Use
方法中,创建的客户端与using语句一起使用。我已经阅读了Using语句的避免问题,但似乎我不知道你想处理异常的策略,因此我只是尝试和重新抛出。 -
根据1,我认为一个线程安全的方式通过锁自动处置,继承
IsDisposed
和ThisLock
被使用。Close
和Abort
在那里做相应的事情。 -
哦十!
ServiceProxy2
和ServiceProxy1
类仅供示例,ServiceProxy2
派生自ServiceProxy1
。
代码看起来冗长,但实际上非常简单的设计。只要把问题报告给我,我会尽力改正的。希望帮助andgood 锁定!
我通过使用ServiceClient1 : IServiceProxyFactory<ServiceClient1>
技巧将ServiceProxy1
类合并到ServiceClient1
中来实现。
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();
}
}
}
}
现在我可以输入:
Service<ServiceClient1>.Use(svc => svc.Method());