我的一位同事開發了這個解決方案:
/// <summary>
/// Proxy for executing generic service methods
/// </summary>
public class ServiceProxy
{
/// <summary>
/// Execute service method and get return value
/// </summary>
/// <typeparam name="C">Type of service</typeparam>
/// <typeparam name="T">Type of return value</typeparam>
/// <param name="action">Delegate for implementing the service method</param>
/// <returns>Object of type T</returns>
public static T Execute<C, T>(Func<C, T> action) where C : class, ICommunicationObject, new()
{
C svc = null;
T result = default(T);
try
{
svc = new C();
result = action.Invoke(svc);
svc.Close();
}
catch (FaultException ex)
{
// Logging goes here
// Service Name: svc.GetType().Name
// Method Name: action.Method.Name
// Duration: You could note the time before/after the service call and calculate the difference
// Exception: ex.Reason.ToString()
if (svc != null)
{
svc.Abort();
}
throw;
}
catch (Exception ex)
{
// Logging goes here
if (svc != null)
{
svc.Abort();
}
throw;
}
return result;
}
}
而且其採用的例子:
public class SecurityServiceProxy
{
public static UserInformation GetUserInformation(Guid userId)
{
var result = ServiceProxy.Execute<MySecurityService, UserInformation>
(
svc => svc.GetUserInformation(userId)
);
return result;
}
public static bool IsUserAuthorized(UserCredentials creds, ActionInformation actionInfo)
{
var result = ServiceProxy.Execute<MySecurityService, bool>
(
svc => svc.IsUserAuthorized(creds, actionInfo)
);
return result;
}
}
在這個假的情況下,我們使用的是從MySecurityService
,GetUserInformation
和IsUserAuthorized
兩種方法。 GetUserInformation
以Guid
作爲參數並返回UserInformation
對象。 IsUserAuthorized
需要一個UserCredentials
和ActionInformation
對象,並返回一個bool
用戶是否被授權。
此代理也是緩存可緩存服務調用結果的理想之處。
如果您需要向服務器發送參數,可能會有更通用的方式,但我認爲您需要爲其創建特定的代理。例如:
public interface ISecuredService
{
public UserCredentials Credentials { get; set; }
}
/// <summary>
/// Proxy for executing generic UserCredentials secured service methods
/// </summary>
public class SecuredServiceProxy
{
/// <summary>
/// Execute service method and get return value
/// </summary>
/// <typeparam name="C">Type of service</typeparam>
/// <typeparam name="T">Type of return value</typeparam>
/// <param name="credentials">Service credentials</param>
/// <param name="action">Delegate for implementing the service method</param>
/// <returns>Object of type T</returns>
public static T Execute<C, T>(UserCredentials credentials, Func<C, T> action) where C : class, ICommunicationObject, ISecuredService, new()
{
C svc = null;
T result = default(T);
try
{
svc = new C();
svc.Credentials = credentials;
result = action.Invoke(svc);
svc.Close();
}
catch (FaultException ex)
{
// Logging goes here
// Service Name: svc.GetType().Name
// Method Name: action.Method.Name
// Duration: You could note the time before/after the service call and calculate the difference
// Exception: ex.Reason.ToString()
if (svc != null)
{
svc.Abort();
}
throw;
}
catch (Exception ex)
{
// Logging goes here
if (svc != null)
{
svc.Abort();
}
throw;
}
return result;
}
}
有很多模式可以通過互聯網處理這些事情,你只需要確保你適當地關閉了你的服務並且不會[使用using語句的錯誤](http: //msdn.microsoft.com/en-us/library/aa355056.aspx)。 – 2012-07-10 22:37:31
這[封裝服務](http://stackoverflow.com/a/6020625/1257607)也可能有幫助。但更多的是封裝整個事情。 – DanielV 2016-09-09 12:24:39