我們將 Praxedo 用于多種服務,其中許多服務在不同的 SOAP API 上,這些 API 與實體化和消費非常相似。
我不想重復代碼,而是想用一種通用的方法來做到這一點。
我創建了這個工廠類:
using PraxedoIntegration.Common.Configurations;
using System;
using System.ServiceModel;
using System.ServiceModel.Channels;
using WcfCoreMtomEncoder;
namespace PraxedoV6.ManagerClientWrappers.Helpers
{
public class PraxedoClientFactory
{
private readonly PraxedoSettings _praxedoSettings;
public PraxedoClientFactory(
PraxedoSettings praxedoSettings
) =>
_praxedoSettings = praxedoSettings ?? throw new ArgumentNullException(nameof(praxedoSettings));
public T Create<T, TChannel>(Uri endpoint, HttpsTransportBindingElement bindingElement)
where T : ClientBase<TChannel>, new()
where TChannel : class
{
MtomMessageEncoderBindingElement encoding = CreateMtomMessageEncoderBindingElement();
CustomBinding customBinding = new(encoding, bindingElement);
T managerClient = (T)Activator.CreateInstance(typeof(T), new object[] { customBinding, endpoint });
_praxedoSettings.AddAuthorizationTo(managerClient);
return Authorize<T, TChannel>(managerClient);
}
private static MtomMessageEncoderBindingElement CreateMtomMessageEncoderBindingElement() =>
new(new TextMessageEncodingBindingElement
{
MessageVersion = MessageVersion.CreateVersion(EnvelopeVersion.Soap12, AddressingVersion.None)
});
public T Authorize<T, TChannel>(T managerClient)
where T : ClientBase<TChannel>, new()
where TChannel : class
{
_ = new OperationContextScope(managerClient.InnerChannel);
OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name]
= _praxedoSettings.ToHttpRequestMessageProperty();
return managerClient;
}
}
}
它編譯得很好。
但是當我嘗試使用它時,例如:
_customerManagerClient = praxedoClientFactory.Create<CustomerManagerClient, CustomerManagerV6.CustomerManager>(
_praxedoSettings.CustomerManagerEndpoint,
new HttpsTransportBindingElement()
我收到運行時錯誤,例如:
?
WorkflowTests.TaskProcessor.NewOrg.CreateCustomerAndLocationActionDiagnosticTool.CreateCustomerAndLocationInPraxedoTest 來源:CreateCustomerAndLocationActionDiagnosticTool.cs line 15
持續時間:23 ms訊息:System.MissingMethodException:未找到型別“CustomerManagerV6.CustomerManagerClient”的建構式。
Stack Trace: RuntimeType.CreateInstanceImpl(BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture) Activator.CreateInstance(Type type, BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture, Object[] activationAttributes) Activator.CreateInstance(Type type, Object[] args) PraxedoClientFactory.Create[T,TChannel](Uri endpoint, HttpsTransportBindingElement bindingElement) line 25 CustomerManagerClientWrapper.ctor(PraxedoClientFactory praxedoClientFactory, PraxedoSettings praxedoSettings, PraxedoThrottleOut praxedoThrottleOut) line 30 CreateCustomerAndLocationActionDiagnosticTool.CreateCustomerAndLocationInPraxedoTest() line 22 --- End of stack trace from previous location ---
在這個實體中CustomerManagerClient是一個從抽象繼承System.ServiceModel.ClientBase<CustomerManagerV6.CustomerManager>并實作介面的類CustomerManagerV6.CustomerManager(所有這些都是從 WSDL 自動生成的每個代碼)。
在另一個實體中,我們擁有BusinessEventManagerClient(您可能會預測)從抽象繼承System.ServiceModel.ClientBase<BusinessEventManagerV6.BusinessEventManagerClient>并實作介面BusinessEventManagerV6.BusinessEventManagerClient(所有 [再次] 根據從 WSDL 自動生成的代碼)。
我們還有大約六個類似的“經理客戶”。
我是否Create()使用正確的型別引數和約束宣告方法?我是否正確呼叫它?還有什么我應該做的嗎?我是在嘗試做一些不可能的事情嗎?
uj5u.com熱心網友回復:
找出問題....我忘記將 my 轉換Uri endpoint為 an EndpointAddress,如下所示:
public T Create<T, TChannel>(Uri endpoint, HttpsTransportBindingElement bindingElement)
where T : ClientBase<TChannel>, TChannel, new()
where TChannel : class
{
MtomMessageEncoderBindingElement encoding = CreateMtomMessageEncoderBindingElement();
CustomBinding customBinding = new(encoding, bindingElement);
EndpointAddress endpointAddress = new(endpoint);
T managerClient = (T)Activator.CreateInstance(typeof(T), new object[] { customBinding, endpointAddress });
_praxedoSettings.AddAuthorizationTo(managerClient);
return Authorize<T, TChannel>(managerClient);
}
...所以建構式得到了錯誤型別的物件。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/311179.html
下一篇:為多種型別實作泛型
