我有一个插件模型体系结构,可以创建我的Restful WCF服务。
(从WCF迁移到Web Api还需要几年时间,因此,迁移到Web Api并不是完全解决方案。)
我已经解耦了彼此不引用的WCF微服务。
EnityAWebService从配置中知道服务EntityBWebService存在,但未引用它。
EntityAWebService和EntityBWebService是插件。这样,它们可以在同一站点上加载。
EntityAWebService使用配置信息来调用EntityBWebService。 EntityBWebService可以在同一服务器上,也可以在其他服务器上。 -如果在其他服务器上,代码将继续使用HttpClient。 -如果在同一台服务器上,则发送消息并通过通道发送,而无需通过HttpClient,操作系统的网络和IIS。
下面是体系结构。橙色是我想要创建的。
使用HttpClient表示EntityAWebService发送一条消息,该消息将进入操作系统网络层并通过IIS。两者都不是必需的。这会导致性能问题,并且随着Entity插件的增加,套接字的数量也会增加,即使使用单例httpclient,套接字也会泄漏。
体系结构中的橙色是尚不存在的。
代码知道要为实体B Web服务调用的Url,消息内容和标头。我将如何在橙色框表示的代码中模拟IIS通过行为将呼叫转发到端点的功能?
仅供参考,我当前的项目太复杂而无法发布,因此我将创建一个示例并尽快发布。
答案 0 :(得分:0)
原来,我不需要使用命名管道。但是,研究如何使用命名管道教会了我需要知道的知识。我只需要使用反射和ChannelFactory。由于用于IIS托管的ChannelFactory已经存在,因此命名管道将是多余的。
示例项目在这里:https://github.com/rhyous/DecoupledWcfServices
下面是适当的代码段(解决方案的内容)。
using System;
using System.Collections.Specialized;
using System.ServiceModel;
using System.ServiceModel.Description;
using System.ServiceModel.Web;
namespace DecoupledWcfServices
{
/// <summary>
/// Service 1 and Service 2 are in the same namespace in this project
/// </summary>
public class MessageBus
{
public string CallOtherWcfService(string url, object content, NameValueCollection headers)
{
var service = GetServiceName(url);
try
{
var netPipeUrl = $"http://localhost:54412/{service}/{service}.svc";
var serviceContractType = typeof(IService2);
var genericChannelFactoryType = typeof(WebChannelFactory<>).MakeGenericType(serviceContractType);
var binding = new WebHttpBinding();
var channelFactory = Activator.CreateInstance(genericChannelFactoryType, binding, new Uri(netPipeUrl)) as WebChannelFactory<IService2>; // I actually won't know it is an IService2 in my project, but getting this far should be enough
var proxy = channelFactory.CreateChannel() as IService2;
using (new OperationContextScope((IContextChannel)proxy))
{
var task = proxy.GetData("some data"); // Might need more work here to know which method to call based on the Url
task.Wait();
return task.Result; // Serialized JSON
}
}
catch (Exception)
{
throw;
}
}
internal string GetServiceName(string url)
{
var index = url.IndexOf(".svc");
var sub = url.Substring(0, index);
index = sub.LastIndexOf("/") + 1;
var sub2 = url.Substring(index, sub.Length - index);
return sub2;
}
}
}