在.NET5中替代WCF进行通信的解决方案
一、先说说WCF和WebService的概念。
参考文章:https://www.cnblogs.com/zhao123/p/5599096.html
Web Service 是一种可以接收从Internet(互联网)或者Intranet(内联网)上的其它系统中传递过来的请求,轻量级的独立的通讯技术。是通过SOAP在Web上提供的软件服务,使用WSDL文件进行说明,并通过UDDI进行注册。WebService可用基于XML的SOAP来表示数据和调用请求,并且通过HTTP协议来传输这些XML格式的数据。严格来说是行业标准,也就是WebService规范,也称作WS-*规范,既不是框架,也不是技术。
XML:(Extensible Markup Language)扩展型可标记语言。面向短期的临时数据处理、面向万维网络,是Soap的基础。
Soap:(Simple Object Access Protocol)简单对象存取协议。当用户通过UDDI找到你的WSDL描述文档后,他通过可以SOAP调用你建立的Web服务中的一个或多个操作。SOAP是XML文档形式的调用方法的规范,它可以支持不同的底层接口,像HTTP(S)或者SMTP。
WSDL:(Web Services Description Language) WSDL 文件是一个 XML 文档,用于说明一组 SOAP 消息以及如何交换这些消息。大多数情况下由软件自动生成和使用。
UDDI (Universal Description, Discovery, and Integration) 是一个主要针对Web服务供应商和使用者的新项目。UDDI是一种根据描述文档来引导系统查找相应服务的机制。UDDI利用SOAP消息机制(标准的XML/HTTP)来发布,编辑,浏览以及查找注册信息。它采用XML格式来封装各种不同类型的数据,并且发送到注册中心或者由注册中心来返回需要的数据。
ASP.NET WebService:微软的Web服务实现称为ASP.NET WebService。
微软提供了Web服务的开发框架,属于ASP.NETFramework的一部分,但是支持早起的WS规范。比如SOAP1.1。
PS:后来微软做了ASP.NETWebService的安全,性能,数据加密、解密,托管宿主等多方面的扩展,称为WSE系列,这个是过度产品,最高到WSE3.0.后来就是WCF时代。
WCF(之前的版本名为“Indigo”)是使用托管代码建立和运行面向服务(ServiceOriented)应用程序的统一框架。它使得开发者能够建立一个跨平台的安全、可信赖、事务性的解决方案,且能与已有系统兼容协作。
WCF 能够创建兼容 Web 服务的服务,也就是说可以创建能够与Web 服务互联互通的服务,他们两个并不能用简单包含或者等同关系来表述。WCF 是一套框架,用来创建各种服务。其中包括创建 Web服务(采用 basicHttpBinding绑定的服务就是一个Web 服务)。
二、使用SoapCore
那么在.NET5.0已经不支持WCF框架的情况下,我们只能使用WebService来进行跨平台的通信。这里需要引用一个包SoapCore。他是通过中间件的方式来进行SOAP协议的解析,具体参考:https://www.cnblogs.com/linezero/p/aspnetcoresoap.html
SoapCore包的源码:https://github.com/DigDes/SoapCore
使用SoapCore开发示例:https://www.cnblogs.com/xyyhcn/p/14862728.html
三、使用Dapper
在示例Demo成功之后,我们可以开始进行正式的业务逻辑处理。
首先少不了的是对数据库的数据交互。在这里我使用Dapper代替EF。Dapper更轻量级,只要通过Nuget引用Dapper.SqlBuilder包和System.Data.SqlClient系统包(用于支持SqlConnection)。
我们建立AppSetting类来提取appsettings.json文件中配置的数据(比如数据库链接地址)。
public class AppSettings
{
private static readonly IConfigurationRoot _config;
public static class ConnectionStrings
{
public static string Database => _config["ConnectionStrings:Default"];
}
}
再建立一个ConnectionFactory类来封装对数据库的连接。
public class ConnectionFactory
{
public static IDbConnection GetConnection()
{
return new SqlConnection(AppSettings.ConnectionStrings.Database);
}
}
建立仓储接口ICustomerRepository来封装与数据库的交互(sql语句)。
在接口中定义Get和Add方法。
public interface ICustomerRepository
{
Task<Customer> Get(string code,string name);
Task Add(Customer model);
}
建立CustomerRepository实现ICustomerRepository的接口。
public class CustomerRepository : ICustomerRepository
{
private readonly string TenantId = AppSettings.Tenants.FindTenantWithIndex(0).Id;
public async Task<Customer> Getr(string code, string name)
{
using IDbConnection connection = ConnectionFactory.GetConnection();
SqlBuilder build = new SqlBuilder();
var sql = @"
select * from Customer_Project
where IsDeleted=0
and TenantId=@TenantId
and ( Code =@Code or Name=@Name)";
var selector = build.AddTemplate(sql, new
{
TenantId = TenantId,
Code = code,
Name = name
});
var results = await connection.QueryAsync<Customer>(selector.RawSql, selector.Parameters);
return results.FirstOrDefault();
}
public async Task Add(Customer model)
{
model.TenantId = Guid.Parse(TenantId);
var sql = @"INSERT INTO [dbo].[Customer_Info]
([Id]
,[CreationTime]
,[CreatorId]
,[TenantId]
,[Code]
,[Name]
,[ManagerId]
,[CategoryCode]
,[Status])
VALUES
(@Id
,@CreationTime
,@CreatorId
,@TenantId
,@Code
,@Name
,@ManagerId
,@CategoryCode
,@Status)
";
using IDbConnection connection = ConnectionFactory.GetConnection();
var result = await connection.ExecuteAsync(sql, model);
}
}
从代码中可以看到,首先我们通过ConnectionFactory和数据库进行连接,即using IDbConnection connection = ConnectionFactory.GetConnection();
通过SqlBuilder来进行sql语句的值填充。最后执行QueryAsync/ExecuteAsync等方法对数据库进行增删改查操作。
四、Service实现业务逻辑
建立IMoldService对外提供接口。
[ServiceContract]
public interface IMoldService
{
[OperationContract]
Task<string> SyncMold(string input,string opt="I");
}
再建立MoldService实现IMoldService的接口,处理业务逻辑。