gpt4 book ai didi

c# - 在可重用类中封装多个服务引用操作

转载 作者:太空宇宙 更新时间:2023-11-03 21:58:00 26 4
gpt4 key购买 nike

我有一个 .NET 服务引用,我想将其封装到一个可重用的类中。

我典型的调用看起来像这样:

// instantiate the api and set credentials
ApiClient api = new ApiClient();
api.Credentials.UserName.UserName = "blah";
api.Credentials.UserName.Password = "blahblah";

// operation-specific search parameter object
SomethingSearch search = new SomethingSearch();
search.Key = "blah";

Result[] result = api.GetSomething(search);

api.Close();

其他调用在调用的操作和搜索参数对象上有所不同。

问题是,我不知道如何将 API 操作的名称(即 GetSomething() 和特定于操作的搜索对象 ( SomethingSearch))传递到类中。

我怎样才能做到这一点?我不是要求为我完成工作,但我不确定从哪里开始。我相信这与 Func<T> 有关和代表,但令人尴尬的是,我对他们缺乏经验。

最佳答案

我的一位同事开发了这个解决方案:

/// <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 的两种方法, GetUserInformationIsUserAuthorized . GetUserInformation需要 Guid作为参数并返回 UserInformation目的。 IsUserAuthorized需要 UserCredentialsActionInformation对象,并返回一个 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;
}
}

关于c# - 在可重用类中封装多个服务引用操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11422010/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com