Compare commits

...

10 Commits

Author SHA1 Message Date
Kimdiego2098
99eef8fb28 更新依赖包 2023-12-06 19:14:42 +08:00
Kimdiego2098
47e7685d39 串口代码整理 2023-12-06 18:54:33 +08:00
Kimdiego2098
b6ea596ade 整理代码 2023-12-06 18:35:52 +08:00
Kimdiego2098
44d60b469b 同步ts 2023-12-06 15:48:55 +08:00
Kimdiego2098
51087408df 同步ts 2023-12-06 15:16:54 +08:00
Kimdiego2098
96226d9e6e 同步ts 2023-12-06 14:56:12 +08:00
Kimdiego2098
28f0f62424 同步ts 2023-12-06 11:35:57 +08:00
Kimdiego2098
2e772a8cd4 同步touchsocket 2023-12-06 09:16:00 +08:00
Kimdiego2098
3fd192f0cf 变量表达式编辑 改为 多行文本框 2023-12-06 07:42:07 +08:00
Kimdiego2098
d16ae81961 更新demo;更新kafka 生成事件; 2023-12-04 20:28:36 +08:00
184 changed files with 4678 additions and 3851 deletions

View File

@@ -3,7 +3,7 @@
<ImplicitUsings>enable</ImplicitUsings>
<TargetFrameworks>net6.0;net8.0;</TargetFrameworks>
<Version>4.0.0.7</Version>
<Version>4.0.0.8</Version>
<LangVersion>latest</LangVersion>
<Authors>Diego</Authors>
<Product>ThingsGateway</Product>

View File

@@ -24,7 +24,6 @@ public class Startup : AppStartup
public void ConfigureServices(IServiceCollection services)
{
services.ThingsGatewayComponentsConfigureServices();
services.AddScoped<UserResoures>();
}

View File

@@ -3,6 +3,7 @@
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.SignalR.Client" Version="8.0.0" />
<PackageReference Include="Masa.Blazor.SomethingSkia" Version="1.2.2" />
</ItemGroup>

View File

@@ -35,6 +35,7 @@ public class Startup : AppStartup
{
WorkerId = 4// 取值范围0~63
});
services.ThingsGatewayCoreConfigureServices();
services.AddComponent<LoggingConsoleComponent>();//启动控制台日志格式化组件
ThingsGateway.Core.TypeExtensions.DefaultFuncs.Add(a => a.GetCustomAttribute<SqlSugar.SugarColumn>()?.ColumnDescription);

View File

@@ -5,8 +5,10 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Furion.Extras.Authentication.JwtBearer" Version="4.9.1.8" />
<PackageReference Include="SqlSugarCore" Version="5.1.4.122" />
<PackageReference Include="Furion.Pure" Version="4.9.1.11" />
<PackageReference Include="Furion.Extras.ObjectMapper.Mapster" Version="4.9.1.11" />
<PackageReference Include="Furion.Extras.Authentication.JwtBearer" Version="4.9.1.11" />
<PackageReference Include="SqlSugarCore" Version="5.1.4.126" />
<PackageReference Include="UAParser" Version="3.1.47" />
<PackageReference Include="Yitter.IdGenerator" Version="1.0.14" />
</ItemGroup>

View File

@@ -19,7 +19,7 @@ using Microsoft.Extensions.DependencyInjection;
namespace ThingsGateway.Components;
public static class ConfigureService
public static class ServiceExtensions
{
/// <inheritdoc/>
public static void ThingsGatewayComponentsConfigureServices(this IServiceCollection services)
@@ -65,9 +65,7 @@ public static class ConfigureService
{ nameof(MTimeline), new Dictionary<string, object>() { { nameof(MTimeline.Dense), true } } },
{ nameof(MToolbar), new Dictionary<string, object>() { { nameof(MToolbar.Dense), true } } },
{ "MTreeview", new Dictionary<string, object>() { { "Dense", true } } },
{ nameof(PImageCaptcha), new Dictionary<string, object>() { { nameof(PImageCaptcha.Dense), true } } }
{ "PImageCaptcha", new Dictionary<string, object>() { { "Dense", true } } }
};
options.ConfigureTheme(theme =>
@@ -98,6 +96,7 @@ public static class ConfigureService
services.AddScoped<InitTimezone>();
services.AddScoped<AjaxService>();
services.AddScoped<CookieStorage>();
services.AddScoped<IDefaultTimezoneOffsetAccessor, DefaultTimezoneOffsetAccessor>();
}
}

View File

@@ -1,4 +1,4 @@
#region copyright
#region copyright
//------------------------------------------------------------------------------
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
// 此代码版权除特别声明外的代码归作者本人Diego所有
@@ -10,15 +10,12 @@
//------------------------------------------------------------------------------
#endregion
namespace ThingsGateway.Foundation.Serial;
namespace ThingsGateway.Components;
/// <summary>
/// 字节事件
/// </summary>
public class SerialReceivedEventArgs : TouchSocketEventArgs
public class DefaultTimezoneOffsetAccessor : IDefaultTimezoneOffsetAccessor
{
/// <summary>
/// 数据块
/// </summary>
public ByteBlock UserToken { get; set; }
}
public TimeSpan GetTimezoneOffsetResult()
{
return TimeSpan.FromHours(8);
}
}

View File

@@ -0,0 +1,8 @@

namespace ThingsGateway.Components
{
public interface IDefaultTimezoneOffsetAccessor
{
TimeSpan GetTimezoneOffsetResult();
}
}

View File

@@ -10,9 +10,6 @@
//------------------------------------------------------------------------------
#endregion
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
namespace ThingsGateway.Components;
/// <summary>
@@ -43,17 +40,11 @@ public class InitTimezone : IDisposable
/// <param name="jsRuntime"></param>
/// <param name="storage"></param>
/// <param name="serviceProvider"></param>
public InitTimezone(IJSRuntime jsRuntime, CookieStorage storage, IServiceProvider serviceProvider)
public InitTimezone(IJSRuntime jsRuntime, CookieStorage storage, IDefaultTimezoneOffsetAccessor defaultTimezoneOffsetAccessor)
{
IHttpContextAccessor httpContextAccessor = serviceProvider.GetService<IHttpContextAccessor>();
_jsRuntime = jsRuntime;
_storage = storage;
var httpContext = httpContextAccessor?.HttpContext;
if (httpContext is not null)
{
var timezoneOffsetResult = httpContext.Request.Cookies[_timezoneOffsetKey];
_timezoneOffset = TimeSpan.FromMinutes(Convert.ToDouble(timezoneOffsetResult));
}
_timezoneOffset = defaultTimezoneOffsetAccessor.GetTimezoneOffsetResult();
}
/// <summary>
/// 获取Web客户端时差

View File

@@ -3,7 +3,6 @@
<ItemGroup>
<PackageReference Include="Masa.Blazor" Version="1.2.2" />
<PackageReference Include="Masa.Blazor.SomethingSkia" Version="1.2.2" />
</ItemGroup>
<ItemGroup>

View File

@@ -10,8 +10,6 @@
//------------------------------------------------------------------------------
#endregion
using Furion.DependencyInjection;
using Mapster;
using Microsoft.Extensions.Caching.Memory;
@@ -23,8 +21,9 @@ namespace ThingsGateway.Core;
/// <summary>
/// 系统内存缓存
/// </summary>
public class MemoryCache : ISingleton
public class MemoryCache
{
public static MemoryCache Instance { get; private set; } = new();
private const string intervalStr = "---___---";
private readonly Microsoft.Extensions.Caching.Memory.MemoryCache _memoryCache = new(new MemoryCacheOptions());
private readonly Microsoft.Extensions.Caching.Memory.MemoryCache _prefixmemoryCache = new(new MemoryCacheOptions());

View File

@@ -10,20 +10,15 @@
//------------------------------------------------------------------------------
#endregion
using Furion;
using Microsoft.Extensions.DependencyInjection;
namespace ThingsGateway.Core;
/// <summary>
/// Startup
/// </summary>
[AppStartup(9999)]
public class Startup : AppStartup
public static class ServiceExtensions
{
public void ConfigureServices(IServiceCollection services)
/// <inheritdoc/>
public static void ThingsGatewayCoreConfigureServices(this IServiceCollection services)
{
services.AddSingleton(a => MemoryCache.Instance);
}
}

View File

@@ -10,8 +10,6 @@
//------------------------------------------------------------------------------
#endregion
using Furion;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Globalization;
@@ -90,7 +88,7 @@ public static class TypeExtensions
public static string GetDescription(this Type modelType, string name, Func<MemberInfo, string> func = null)
{
var cacheKey = $"{nameof(GetDescription)}-{CultureInfo.CurrentUICulture.Name}-{modelType.FullName}-{name}-{modelType.TypeHandle.Value}";
var str = App.GetService<MemoryCache>().GetOrCreate(cacheKey, entry =>
var str = MemoryCache.Instance.GetOrCreate(cacheKey, entry =>
{
string dn = default;
{

View File

@@ -1,8 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk">
<ItemGroup>
<PackageReference Include="Furion.Pure" Version="4.9.1.8" />
<PackageReference Include="Furion.Extras.ObjectMapper.Mapster" Version="4.9.1.8" />
<PackageReference Include="Mapster" Version="7.4.0" />
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="8.0.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
</ItemGroup>

View File

@@ -12,6 +12,8 @@
using Photino.Blazor;
using ThingsGateway.Core;
namespace ThingsGateway.Foundation.Demo;
internal class Program
@@ -23,11 +25,10 @@ internal class Program
var appBuilder = PhotinoBlazorAppBuilder.CreateDefault(args);
Serve.RunNative();
appBuilder.RootComponents.Add<App>("#app");
appBuilder.Services.ThingsGatewayComponentsConfigureServices();
appBuilder.Services.ThingsGatewayCoreConfigureServices();
var app = appBuilder.Build();
app.MainWindow.SetTitle("ThingsGateway.Foundation.Demo");
app.MainWindow.SetIconFile("wwwroot/favicon.ico");

View File

@@ -18,10 +18,10 @@
<MCard Flat Class="pa-2 my-1" Style="width:100%">
<div class="mb-4">通道配置</div>
<MRow Justify="JustifyTypes.Start" Align="AlignTypes.Center">
<MTextField Style="max-width:100px" Class="ma-1" Outlined Label=@(_serialProperty.Description(x => x.PortName)) Dense HideDetails="@("auto")" @bind-Value=@_serialProperty.PortName />
<MTextField Style="max-width:100px" Class="ma-1" Outlined Label=@(_serialProperty.Description(x => x.BaudRate)) Dense HideDetails="@("auto")" @bind-Value=@_serialProperty.BaudRate />
<MTextField Style="max-width:100px" Class="ma-1" Outlined Label=@(_serialProperty.Description(x => x.DataBits)) Dense HideDetails="@("auto")" @bind-Value=@_serialProperty.DataBits />
<MSelect Class="ma-1 " Style="max-width:200px" Outlined @bind-Value="_serialProperty.Parity" Label="@(_serialProperty.Description(x => x.Parity))"
<MTextField Style="max-width:100px" Class="ma-1" Outlined Label=@(_serialPortOption.Description(x => x.PortName)) Dense HideDetails="@("auto")" @bind-Value=@_serialPortOption.PortName />
<MTextField Style="max-width:100px" Class="ma-1" Outlined Label=@(_serialPortOption.Description(x => x.BaudRate)) Dense HideDetails="@("auto")" @bind-Value=@_serialPortOption.BaudRate />
<MTextField Style="max-width:100px" Class="ma-1" Outlined Label=@(_serialPortOption.Description(x => x.DataBits)) Dense HideDetails="@("auto")" @bind-Value=@_serialPortOption.DataBits />
<MSelect Class="ma-1 " Style="max-width:200px" Outlined @bind-Value="_serialPortOption.Parity" Label="@(_serialPortOption.Description(x => x.Parity))"
Items=@(typeof(Parity).GetEnumList())
MenuProps="@(props => { props.Auto = true; props.OffsetY = true; })"
ItemText=@((u) =>u.Description)
@@ -29,7 +29,7 @@
HideDetails=@("auto") Height="30"
Dense>
</MSelect>
<MSelect Class="ma-1 " Style="max-width:200px" Outlined @bind-Value="_serialProperty.StopBits" Label="@(_serialProperty.Description(x => x.StopBits))"
<MSelect Class="ma-1 " Style="max-width:200px" Outlined @bind-Value="_serialPortOption.StopBits" Label="@(_serialPortOption.Description(x => x.StopBits))"
Items=@(typeof(StopBits).GetEnumList())
MenuProps="@(props => { props.Auto = true; props.OffsetY = true; })"
ItemText=@((u) =>u.Description)

View File

@@ -13,39 +13,39 @@
namespace ThingsGateway.Foundation.Demo;
/// <inheritdoc/>
public partial class SerialSessionPage : IDisposable
public partial class SerialPortClientPage : IDisposable
{
/// <summary>
/// 日志输出
/// </summary>
public Action<LogLevel, object, string, Exception> LogAction;
private readonly SerialProperty _serialProperty = new();
private readonly SerialPortOption _serialPortOption = new();
private TouchSocketConfig _config;
private SerialSession _serialSession { get; set; } = new();
private SerialPortClient _serialPortClient { get; set; } = new();
/// <summary>
/// <inheritdoc/>
/// </summary>
public void Dispose()
{
_serialSession.SafeDispose();
_serialPortClient.SafeDispose();
}
/// <summary>
/// 获取对象
/// </summary>
/// <returns></returns>
public SerialSession GetSerialSession()
public SerialPortClient GetSerialPortClient()
{
_config ??= new TouchSocketConfig();
var LogMessage = new LoggerGroup() { LogLevel = LogLevel.Trace };
LogMessage.AddLogger(new EasyLogger(LogOut) { LogLevel = LogLevel.Trace });
_config.ConfigureContainer(a => a.RegisterSingleton<ILog>(LogMessage));
_config.SetSerialProperty(_serialProperty);
_config.SetSerialPortOption(_serialPortOption);
//载入配置
_serialSession.Setup(_config);
return _serialSession;
_serialPortClient.Setup(_config);
return _serialPortClient;
}
internal void StateHasChangedAsync()
{
@@ -63,7 +63,7 @@ public partial class SerialSessionPage : IDisposable
var LogMessage = new LoggerGroup() { LogLevel = LogLevel.Trace };
LogMessage.AddLogger(new EasyLogger(LogOut) { LogLevel = LogLevel.Trace });
_config.ConfigureContainer(a => a.RegisterSingleton<ILog>(LogMessage));
_serialSession.Setup(_config);
_serialPortClient.Setup(_config);
}
base.OnAfterRender(firstRender);
}
@@ -80,8 +80,8 @@ public partial class SerialSessionPage : IDisposable
{
try
{
_serialSession.Close();
await GetSerialSession().ConnectAsync();
_serialPortClient.Close();
await GetSerialPortClient().ConnectAsync();
}
catch (Exception ex)
{
@@ -93,7 +93,7 @@ public partial class SerialSessionPage : IDisposable
{
try
{
_serialSession.Close();
_serialPortClient.Close();
}
catch (Exception ex)
{

View File

@@ -16,6 +16,6 @@ global using System.Threading.Tasks;
global using ThingsGateway.Components;
global using ThingsGateway.Foundation.Core;
global using ThingsGateway.Foundation.Serial;
global using ThingsGateway.Foundation.SerialPorts;
global using ThingsGateway.Foundation.Sockets;

View File

@@ -19,7 +19,7 @@
@using Masa.Blazor;
@namespace ThingsGateway.Foundation.Demo
<SerialSessionPage @ref=_serialSessionPage></SerialSessionPage>
<SerialPortClientPage @ref=_serialPortClientPage></SerialPortClientPage>
<MCard Flat Class="pa-2 my-1" Style="width:100%">
<div class="mb-4">驱动配置</div>

View File

@@ -17,9 +17,9 @@ namespace ThingsGateway.Foundation.Demo;
public partial class DLT645_2007DebugPage
{
/// <summary>
/// SerialSessionPage
/// SerialPortClientPage
/// </summary>
private SerialSessionPage _serialSessionPage;
private SerialPortClientPage _serialPortClientPage;
private DriverDebugUIPage _driverDebugUIPage;
private ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007 _plc;
/// <summary>
@@ -37,15 +37,15 @@ public partial class DLT645_2007DebugPage
//链路基础配置项
var config = new TouchSocketConfig();
config
.SetSerialProperty(new SerialProperty() //串口链路才需要
.SetSerialPortOption(new SerialPortOption() //串口链路才需要
{
PortName = "COM1"
});
var serialSession = new SerialSession();//链路对象
serialSession.Setup(config);
var serialPortClient = new SerialPortClient();//链路对象
serialPortClient.Setup(config);
//创建协议对象,构造函数需要传入对应链路对象
DLT645_2007 plc = new(serialSession)//传入链路
DLT645_2007 plc = new(serialPortClient)//传入链路
{
//协议配置
DataFormat = DataFormat.ABCD,
@@ -69,9 +69,9 @@ public partial class DLT645_2007DebugPage
""", "csharp"));
if (_serialSessionPage != null)
_serialSessionPage.LogAction = _driverDebugUIPage.LogOut;
_plc = new ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007(_serialSessionPage.GetSerialSession());
if (_serialPortClientPage != null)
_serialPortClientPage.LogAction = _driverDebugUIPage.LogOut;
_plc = new ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007(_serialPortClientPage.GetSerialPortClient());
_driverDebugUIPage.Plc = _plc;
//初始化

View File

@@ -17,7 +17,7 @@ namespace ThingsGateway.Foundation.Demo;
public partial class DLT645_2007OverTcpDebugPage
{
/// <summary>
/// SerialSessionPage
/// SerialPortClientPage
/// </summary>
private TcpClientPage _tcpClientPage;
private DriverDebugUIPage _driverDebugUIPage;

View File

@@ -19,7 +19,7 @@
@using Masa.Blazor;
@namespace ThingsGateway.Foundation.Demo
<SerialSessionPage @ref=_serialSessionPage></SerialSessionPage>
<SerialPortClientPage @ref=_serialPortClientPage></SerialPortClientPage>
<MCard Flat Class="pa-2 my-1" Style="width:100%">
<div class="mb-4">驱动配置</div>

View File

@@ -19,9 +19,9 @@ namespace ThingsGateway.Foundation.Demo;
public partial class ModbusRtuDebugPage
{
/// <summary>
/// SerialSessionPage
/// SerialPortClientPage
/// </summary>
private SerialSessionPage _serialSessionPage;
private SerialPortClientPage _serialPortClientPage;
private readonly List<(string Code, string Language)> _sections = new();
private DriverDebugUIPage _driverDebugUIPage;
@@ -41,15 +41,15 @@ public partial class ModbusRtuDebugPage
//链路基础配置项
var config = new TouchSocketConfig();
config
.SetSerialProperty(new SerialProperty() //串口链路才需要
.SetSerialPortOption(new SerialPortOption() //串口链路才需要
{
PortName = "COM1"
});
var serialSession = new SerialSession();//链路对象
serialSession.Setup(config);
var serialPortClient = new SerialPortClient();//链路对象
serialPortClient.Setup(config);
//创建协议对象,构造函数需要传入对应链路对象
ModbusRtu plc = new(serialSession)//传入链路
ModbusRtu plc = new(serialPortClient)//传入链路
{
//协议配置
DataFormat = DataFormat.ABCD,
@@ -72,9 +72,9 @@ public partial class ModbusRtuDebugPage
""", "csharp"));
if (_serialSessionPage != null)
_serialSessionPage.LogAction = _driverDebugUIPage.LogOut;
_plc = new ThingsGateway.Foundation.Adapter.Modbus.ModbusRtu(_serialSessionPage.GetSerialSession());
if (_serialPortClientPage != null)
_serialPortClientPage.LogAction = _driverDebugUIPage.LogOut;
_plc = new ThingsGateway.Foundation.Adapter.Modbus.ModbusRtu(_serialPortClientPage.GetSerialPortClient());
_driverDebugUIPage.Plc = _plc;
//载入配置
StateHasChanged();

View File

@@ -19,7 +19,7 @@ namespace ThingsGateway.Foundation.Demo;
public partial class ModbusRtuOverTcpDebugPage
{
/// <summary>
/// SerialSessionPage
/// SerialPortClientPage
/// </summary>
private TcpClientPage _tcpClientPage;
private DriverDebugUIPage _driverDebugUIPage;

View File

@@ -17,7 +17,7 @@ namespace ThingsGateway.Foundation.Demo;
public partial class ModbusRtuOverUdpDebugPage
{
/// <summary>
/// SerialSessionPage
/// SerialPortClientPage
/// </summary>
private UdpSessionPage _udpSessionPage;
private DriverDebugUIPage _driverDebugUIPage;

View File

@@ -19,7 +19,7 @@
@using Masa.Blazor;
@namespace ThingsGateway.Foundation.Demo
<SerialSessionPage @ref=_serialSessionPage></SerialSessionPage>
<SerialPortClientPage @ref=_serialPortClientPage></SerialPortClientPage>
<MCard Flat Class="pa-2 my-1" Style="width:100%">
<div class="mb-4">驱动配置</div>

View File

@@ -17,9 +17,9 @@ namespace ThingsGateway.Foundation.Demo;
public partial class ModbusSerialServerDebugPage
{
/// <summary>
/// SerialSessionPage
/// SerialPortClientPage
/// </summary>
private SerialSessionPage _serialSessionPage;
private SerialPortClientPage _serialPortClientPage;
private DriverDebugUIPage _driverDebugUIPage;
private ThingsGateway.Foundation.Adapter.Modbus.ModbusSerialServer _plc;
@@ -39,15 +39,15 @@ public partial class ModbusSerialServerDebugPage
//链路基础配置项
var config = new TouchSocketConfig();
config
.SetSerialProperty(new SerialProperty() //串口链路才需要
.SetSerialPortOption(new SerialPortOption() //串口链路才需要
{
PortName = "COM1"
});
var serialSession = new SerialSession();//链路对象
serialSession.Setup(config);
var serialPortClient = new SerialPortClient();//链路对象
serialPortClient.Setup(config);
//创建协议对象,构造函数需要传入对应链路对象
ModbusSerialServer plc = new(serialSession)//传入链路
ModbusSerialServer plc = new(serialPortClient)//传入链路
{
//协议配置
DataFormat = DataFormat.ABCD,
@@ -70,9 +70,9 @@ public partial class ModbusSerialServerDebugPage
""", "csharp"));
if (_serialSessionPage != null)
_serialSessionPage.LogAction = _driverDebugUIPage.LogOut;
_plc = new ThingsGateway.Foundation.Adapter.Modbus.ModbusSerialServer(_serialSessionPage.GetSerialSession());
if (_serialPortClientPage != null)
_serialPortClientPage.LogAction = _driverDebugUIPage.LogOut;
_plc = new ThingsGateway.Foundation.Adapter.Modbus.ModbusSerialServer(_serialPortClientPage.GetSerialPortClient());
_driverDebugUIPage.Plc = _plc;
//载入配置
StateHasChanged();

View File

@@ -21,7 +21,7 @@ public partial class ModbusTcpDebugPage
private ThingsGateway.Foundation.Adapter.Modbus.ModbusTcp _plc;
/// <summary>
/// SerialSessionPage
/// SerialPortClientPage
/// </summary>
private TcpClientPage _tcpClientPage;
/// <summary>

View File

@@ -17,7 +17,7 @@ namespace ThingsGateway.Foundation.Demo;
public partial class ModbusUdpDebugPage
{
/// <summary>
/// SerialSessionPage
/// SerialPortClientPage
/// </summary>
private UdpSessionPage _udpSessionPage;
private DriverDebugUIPage _driverDebugUIPage;

View File

@@ -23,7 +23,7 @@
@using ThingsGateway.Foundation.Core;
@using ThingsGateway.Foundation.Adapter.OPCDA.Da;
@using ThingsGateway.Foundation.Extension;
@using ThingsGateway.Foundation.Serial;
@using ThingsGateway.Foundation.SerialPorts;
@using Masa.Blazor

View File

@@ -25,7 +25,7 @@
@using ThingsGateway.Foundation.Core;
@using ThingsGateway.Foundation.Adapter.OPCUA;
@using ThingsGateway.Foundation.Extension;
@using ThingsGateway.Foundation.Serial;
@using ThingsGateway.Foundation.SerialPorts;
@using Masa.Blazor

View File

@@ -20,7 +20,7 @@
@using ThingsGateway.Foundation.Adapter.Siemens;
@using ThingsGateway.Foundation.Core;
@using ThingsGateway.Foundation.Extension;
@using ThingsGateway.Foundation.Serial;
@using ThingsGateway.Foundation.SerialPorts;
@using Masa.Blazor

View File

@@ -21,7 +21,7 @@ public partial class SiemensDebugPage
private ThingsGateway.Foundation.Adapter.Siemens.SiemensS7PLC _plc;
/// <summary>
/// SerialSessionPage
/// SerialPortClientPage
/// </summary>
private TcpClientPage _tcpClientPage;
/// <summary>

View File

@@ -10,8 +10,6 @@
//------------------------------------------------------------------------------
#endregion
using System.Collections.Generic;
namespace ThingsGateway.Foundation.Demo;
public partial class MainLayout
@@ -105,16 +103,16 @@ public partial class MainLayout
"Title": "OPCUAClient"
}
]
},
{
"Title": "Mqtt",
"Children": [
{
"Href": "/MqttClient",
"Title": "MqttClient"
}
]
}
//{
// "Title": "Mqtt",
// "Children": [
// {
// "Href": "/MqttClient",
// "Title": "MqttClient"
// }
// ]
//}
]

View File

@@ -25,5 +25,5 @@
@using System.Net.Http.Json
@using System.IO;
@using System.Text.Json;
@using ThingsGateway.Foundation.Serial;
@using ThingsGateway.Foundation.SerialPorts;
@using ThingsGateway.Foundation.Sockets;

View File

@@ -14,9 +14,9 @@ using Microsoft.AspNetCore.Components.WebView.WindowsForms;
using Microsoft.Extensions.DependencyInjection;
using System.Diagnostics;
using System.Threading.Tasks;
using ThingsGateway.Components;
using ThingsGateway.Core;
namespace ThingsGateway.Foundation.Demo.Winform
{
@@ -26,14 +26,12 @@ namespace ThingsGateway.Foundation.Demo.Winform
{
InitializeComponent();
IServiceCollection services = null;
IServiceCollection services = new ServiceCollection();
Serve.RunNative(a =>
{
services = a;
services.AddWindowsFormsBlazorWebView();
services.ThingsGatewayComponentsConfigureServices();
});
services.AddWindowsFormsBlazorWebView();
services.ThingsGatewayComponentsConfigureServices();
services.ThingsGatewayCoreConfigureServices();
blazorWebView1.HostPage = "wwwroot/index.html";
blazorWebView1.Services = services.BuildServiceProvider();

View File

@@ -7,6 +7,7 @@
<UseWindowsForms>true</UseWindowsForms>
</PropertyGroup>
<ItemGroup>
<None Remove="favicon.ico" />
</ItemGroup>

View File

@@ -16,13 +16,13 @@ namespace ThingsGateway.Foundation.Adapter.DLT645;
/// <summary>
/// DLT645_2007
/// </summary>
public class DLT645_2007 : ReadWriteDevicesSerialSessionBase, IDLT645_2007
public class DLT645_2007 : ReadWriteDevicesSerialPortClientBase, IDLT645_2007
{
/// <summary>
/// DLT645_2007
/// </summary>
/// <param name="serialSession"></param>
public DLT645_2007(SerialSession serialSession) : base(serialSession)
/// <param name="serialPortClient"></param>
public DLT645_2007(SerialPortClient serialPortClient) : base(serialPortClient)
{
ThingsGatewayBitConverter = new DLT645_2007BitConverter(EndianType.Big);
RegisterByteLength = 2;
@@ -62,7 +62,7 @@ public class DLT645_2007 : ReadWriteDevicesSerialSessionBase, IDLT645_2007
{
EnableFEHead = EnableFEHead
};
SerialSession.SetDataHandlingAdapter(dataHandleAdapter);
SerialPortClient.SetDataHandlingAdapter(dataHandleAdapter);
}

View File

@@ -17,5 +17,5 @@ global using System.Threading;
global using System.Threading.Tasks;
global using ThingsGateway.Foundation.Core;
global using ThingsGateway.Foundation.Serial;
global using ThingsGateway.Foundation.SerialPorts;
global using ThingsGateway.Foundation.Sockets;

View File

@@ -17,5 +17,5 @@ global using System.Threading;
global using System.Threading.Tasks;
global using ThingsGateway.Foundation.Core;
global using ThingsGateway.Foundation.Serial;
global using ThingsGateway.Foundation.SerialPorts;
global using ThingsGateway.Foundation.Sockets;

View File

@@ -16,13 +16,13 @@ namespace ThingsGateway.Foundation.Adapter.Modbus;
/// <summary>
/// ModbusRtu
/// </summary>
public class ModbusRtu : ReadWriteDevicesSerialSessionBase
public class ModbusRtu : ReadWriteDevicesSerialPortClientBase
{
/// <summary>
/// ModbusRtu
/// </summary>
/// <param name="serialSession"></param>
public ModbusRtu(SerialSession serialSession) : base(serialSession)
/// <param name="serialPortClient"></param>
public ModbusRtu(SerialPortClient serialPortClient) : base(serialPortClient)
{
ThingsGatewayBitConverter = new ThingsGatewayBitConverter(EndianType.Big);
RegisterByteLength = 2;
@@ -93,7 +93,7 @@ public class ModbusRtu : ReadWriteDevicesSerialSessionBase
Crc16CheckEnable = Crc16CheckEnable,
CacheTimeout = TimeSpan.FromMilliseconds(CacheTimeout)
};
SerialSession.SetDataHandlingAdapter(dataHandleAdapter);
SerialPortClient.SetDataHandlingAdapter(dataHandleAdapter);
}
/// <inheritdoc/>

View File

@@ -16,10 +16,10 @@ namespace ThingsGateway.Foundation.Adapter.Modbus;
/// <summary>
/// <inheritdoc/>
/// </summary>
public class ModbusSerialServer : ReadWriteDevicesSerialSessionBase, IModbusServer
public class ModbusSerialServer : ReadWriteDevicesSerialPortClientBase, IModbusServer
{
/// <inheritdoc/>
public ModbusSerialServer(SerialSession serialSession) : base(serialSession)
public ModbusSerialServer(SerialPortClient serialPortClient) : base(serialPortClient)
{
ThingsGatewayBitConverter = new ThingsGatewayBitConverter(EndianType.Big);
RegisterByteLength = 2;
@@ -130,7 +130,7 @@ public class ModbusSerialServer : ReadWriteDevicesSerialSessionBase, IModbusServ
{
ModbusSerialServerDataHandleAdapter dataHandleAdapter = new();
dataHandleAdapter.CacheTimeout = TimeSpan.FromMilliseconds(CacheTimeout);
SerialSession.SetDataHandlingAdapter(dataHandleAdapter);
SerialPortClient.SetDataHandlingAdapter(dataHandleAdapter);
}
@@ -165,7 +165,7 @@ public class ModbusSerialServer : ReadWriteDevicesSerialSessionBase, IModbusServ
}
/// <inheritdoc/>
protected override async Task Received(SerialSession client, ReceivedDataEventArgs e)
protected override async Task Received(SerialPortClient client, ReceivedDataEventArgs e)
{
try
{

View File

@@ -253,11 +253,11 @@
ModbusRtu
</summary>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.Modbus.ModbusRtu.#ctor(ThingsGateway.Foundation.Serial.SerialSession)">
<member name="M:ThingsGateway.Foundation.Adapter.Modbus.ModbusRtu.#ctor(ThingsGateway.Foundation.SerialPorts.SerialPortClient)">
<summary>
ModbusRtu
</summary>
<param name="serialSession"></param>
<param name="serialPortClient"></param>
</member>
<member name="P:ThingsGateway.Foundation.Adapter.Modbus.ModbusRtu.Crc16CheckEnable">
<summary>

View File

@@ -10,33 +10,34 @@
//------------------------------------------------------------------------------
#endregion
namespace ThingsGateway.Foundation.Core;
/// <summary>
/// 串口读写设备
/// </summary>
public abstract class ReadWriteDevicesSerialSessionBase : ReadWriteDevicesBase
public abstract class ReadWriteDevicesSerialPortClientBase : ReadWriteDevicesBase
{
/// <summary>
/// <inheritdoc cref="ReadWriteDevicesSerialSessionBase"/>
/// <inheritdoc cref="ReadWriteDevicesSerialPortClientBase"/>
/// </summary>
/// <param name="serialSession"></param>
public ReadWriteDevicesSerialSessionBase(SerialSession serialSession)
/// <param name="serialPortClient"></param>
public ReadWriteDevicesSerialPortClientBase(SerialPortClient serialPortClient)
{
SerialSession = serialSession;
WaitingClientEx = SerialSession.CreateWaitingClient(new() { });
SerialSession.Received -= Received;
SerialSession.Connecting -= Connecting;
SerialSession.Connected -= Connected;
SerialSession.Disconnecting -= Disconnecting;
SerialSession.Disconnected -= Disconnected;
SerialSession.Connecting += Connecting;
SerialSession.Connected += Connected;
SerialSession.Disconnecting += Disconnecting;
SerialSession.Disconnected += Disconnected;
SerialSession.Received += Received;
SerialPortClient = serialPortClient;
WaitingClientEx = SerialPortClient.CreateWaitingClient(new() { });
SerialPortClient.Received -= Received;
SerialPortClient.Connecting -= Connecting;
SerialPortClient.Connected -= Connected;
SerialPortClient.Disconnecting -= Disconnecting;
SerialPortClient.Disconnected -= Disconnected;
SerialPortClient.Connecting += Connecting;
SerialPortClient.Connected += Connected;
SerialPortClient.Disconnecting += Disconnecting;
SerialPortClient.Disconnected += Disconnected;
SerialPortClient.Received += Received;
Logger = SerialSession.Logger;
Logger = SerialPortClient.Logger;
}
/// <summary>
/// 接收解析
@@ -44,88 +45,88 @@ public abstract class ReadWriteDevicesSerialSessionBase : ReadWriteDevicesBase
/// <param name="client"></param>
/// <param name="e"></param>
/// <returns></returns>
protected virtual Task Received(SerialSession client, ReceivedDataEventArgs e)
protected virtual Task Received(SerialPortClient client, ReceivedDataEventArgs e)
{
return EasyTask.CompletedTask;
}
/// <inheritdoc/>
public override ChannelEnum ChannelEnum => ChannelEnum.SerialSession;
public override ChannelEnum ChannelEnum => ChannelEnum.SerialPortClient;
/// <summary>
/// 串口管理对象
/// </summary>
public SerialSession SerialSession { get; }
public SerialPortClient SerialPortClient { get; }
/// <summary>
/// 默认WaitingClientEx
/// </summary>
public virtual IWaitingClient<SerialSession> WaitingClientEx { get; }
public virtual IWaitingClient<SerialPortClient> WaitingClientEx { get; }
/// <inheritdoc/>
public override bool IsConnected()
{
return SerialSession?.CanSend == true;
return SerialPortClient?.CanSend == true;
}
/// <inheritdoc/>
public override void Connect(CancellationToken cancellationToken)
{
SerialSession.Connect();
SerialPortClient.Connect();
}
/// <inheritdoc/>
public override Task ConnectAsync(CancellationToken cancellationToken)
{
return SerialSession.ConnectAsync();
return SerialPortClient.ConnectAsync();
}
/// <inheritdoc/>
public override void Disconnect()
{
if (CascadeDisposal && IsConnected())
SerialSession.Close();
SerialPortClient.Close();
}
/// <inheritdoc/>
public override void Dispose()
{
Disconnect();
SerialSession.Received -= Received;
SerialSession.Connecting -= Connecting;
SerialSession.Connected -= Connected;
SerialSession.Disconnecting -= Disconnecting;
SerialSession.Disconnected -= Disconnected;
if (CascadeDisposal && !SerialSession.DisposedValue)
SerialSession.SafeDispose();
SerialPortClient.Received -= Received;
SerialPortClient.Connecting -= Connecting;
SerialPortClient.Connected -= Connected;
SerialPortClient.Disconnecting -= Disconnecting;
SerialPortClient.Disconnected -= Disconnected;
if (CascadeDisposal && !SerialPortClient.DisposedValue)
SerialPortClient.SafeDispose();
}
/// <inheritdoc/>
public override string ToString()
{
return SerialSession.SerialProperty.ToString();
return SerialPortClient.ToString();
}
private async Task Connected(ISerialSession client, ConnectedEventArgs e)
private async Task Connected(ISerialPortClient client, ConnectedEventArgs e)
{
Logger?.Debug(client.SerialProperty.ToString() + "连接成功");
Logger?.Debug(client.ToString() + "连接成功");
SetDataAdapter();
await EasyTask.CompletedTask;
}
private async Task Connecting(ISerialSession client, SerialConnectingEventArgs e)
private async Task Connecting(ISerialPortClient client, SerialConnectingEventArgs e)
{
Logger?.Debug(client.SerialProperty.ToString() + "正在连接");
Logger?.Debug(client.ToString() + "正在连接");
await EasyTask.CompletedTask;
}
private async Task Disconnected(ISerialSessionBase client, DisconnectEventArgs e)
private async Task Disconnected(ISerialPortClient client, DisconnectEventArgs e)
{
Logger?.Debug(client.SerialProperty.ToString() + "断开连接-" + e.Message);
Logger?.Debug(client.ToString() + "断开连接-" + e.Message);
await EasyTask.CompletedTask;
}
private async Task Disconnecting(ISerialSessionBase client, DisconnectEventArgs e)
private async Task Disconnecting(ISerialPortClient client, DisconnectEventArgs e)
{
Logger?.Debug(client.SerialProperty.ToString() + "正在主动断开连接-" + e.Message);
Logger?.Debug(client.ToString() + "正在主动断开连接-" + e.Message);
await EasyTask.CompletedTask;
}
@@ -150,6 +151,6 @@ public abstract class ReadWriteDevicesSerialSessionBase : ReadWriteDevicesBase
/// <inheritdoc/>
public override void Send(byte[] command, string id = default)
{
SerialSession.Send(command);
SerialPortClient.Send(command);
}
}

View File

@@ -53,8 +53,7 @@ public abstract class ReadWriteDevicesTcpServerBase : ReadWriteDevicesBase
/// <inheritdoc/>
public override Task ConnectAsync(CancellationToken cancellationToken)
{
Connect(cancellationToken);
return EasyTask.CompletedTask;
return TcpService.StartAsync();
}
/// <inheritdoc/>

View File

@@ -48,7 +48,7 @@ public abstract class ReadWriteDevicesUdpSessionBase : ReadWriteDevicesBase
/// <inheritdoc/>
public override Task ConnectAsync(CancellationToken cancellationToken)
{
return Task.FromResult(UdpSession.Start());
return UdpSession.StartAsync();
}
/// <inheritdoc/>

View File

@@ -22,7 +22,7 @@ public enum ChannelEnum
/// <inheritdoc/>
TcpClient = 1,
/// <inheritdoc/>
SerialSession = 2,
SerialPortClient = 2,
/// <inheritdoc/>
UdpSession = 4,
/// <inheritdoc/>

View File

@@ -1,48 +0,0 @@
#region copyright
//------------------------------------------------------------------------------
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
// 此代码版权除特别声明外的代码归作者本人Diego所有
// 源代码使用协议遵循本仓库的开源协议及附加协议
// Gitee源代码仓库https://gitee.com/diego2098/ThingsGateway
// Github源代码仓库https://github.com/kimdiego2098/ThingsGateway
// 使用文档https://diego2098.gitee.io/thingsgateway-docs/
// QQ群605534569
//------------------------------------------------------------------------------
#endregion
using System.IO.Ports;
namespace ThingsGateway.Foundation.Serial;
/// <summary>
/// Connecting
/// </summary>
/// <typeparam name="TClient"></typeparam>
/// <param name="client"></param>
/// <param name="e"></param>
public delegate Task SerialConnectingEventHandler<TClient>(TClient client, SerialConnectingEventArgs e);
/// <summary>
/// 客户端连接事件。
/// </summary>
public class SerialConnectingEventArgs : MsgPermitEventArgs
{
/// <summary>
/// 构造函数
/// </summary>
/// <param name="serialPort"></param>
public SerialConnectingEventArgs(SerialPort serialPort)
{
this.SerialPort = serialPort;
this.IsPermitOperation = true;
}
/// <summary>
/// 客户端Id。该Id的赋值仅在服务器适用。
/// </summary>
public string Id { get; set; }
/// <summary>
/// 新初始化的通信器
/// </summary>
public SerialPort SerialPort { get; private set; }
}

View File

@@ -1,38 +0,0 @@
#region copyright
//------------------------------------------------------------------------------
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
// 此代码版权除特别声明外的代码归作者本人Diego所有
// 源代码使用协议遵循本仓库的开源协议及附加协议
// Gitee源代码仓库https://gitee.com/diego2098/ThingsGateway
// Github源代码仓库https://github.com/kimdiego2098/ThingsGateway
// 使用文档https://diego2098.gitee.io/thingsgateway-docs/
// QQ群605534569
//------------------------------------------------------------------------------
#endregion
namespace ThingsGateway.Foundation.Serial;
/// <summary>
/// 串口附加属性
/// </summary>
public static class SerialConfigExtension
{
/// <summary>
/// 串口属性
/// </summary>
public static readonly DependencyProperty<SerialProperty> SerialProperty =
DependencyProperty<SerialProperty>.Register("SerialProperty", new());
/// <summary>
/// 设置串口
/// </summary>
/// <param name="config"></param>
/// <param name="value"></param>
/// <returns></returns>
public static TouchSocketConfig SetSerialProperty(this TouchSocketConfig config, SerialProperty value)
{
config.SetValue(SerialProperty, value);
return config;
}
}

View File

@@ -1,58 +0,0 @@
#region copyright
//------------------------------------------------------------------------------
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
// 此代码版权除特别声明外的代码归作者本人Diego所有
// 源代码使用协议遵循本仓库的开源协议及附加协议
// Gitee源代码仓库https://gitee.com/diego2098/ThingsGateway
// Github源代码仓库https://github.com/kimdiego2098/ThingsGateway
// 使用文档https://diego2098.gitee.io/thingsgateway-docs/
// QQ群605534569
//------------------------------------------------------------------------------
#endregion
using System.IO.Ports;
namespace ThingsGateway.Foundation.Serial;
/// <summary>
/// SocketExtension
/// </summary>
public static class SerialPortExtensions
{
/// <summary>
/// 会使用同步锁,保证所有数据上缓存区。
/// </summary>
/// <param name="serialPort"></param>
/// <param name="buffer"></param>
/// <param name="offset"></param>
/// <param name="length"></param>
public static void AbsoluteSend(this SerialPort serialPort, byte[] buffer, int offset, int length)
{
lock (serialPort)
{
serialPort.Write(buffer, offset, length);
}
}
/// <summary>
/// 尝试关闭<see cref="SerialPort"/>。不会抛出异常。
/// </summary>
/// <param name="serialPort"></param>
public static void TryClose(this SerialPort serialPort)
{
lock (serialPort)
{
try
{
if (serialPort.IsOpen)
{
serialPort.Close();
}
}
catch
{
}
}
}
}

View File

@@ -1,36 +0,0 @@
#region copyright
//------------------------------------------------------------------------------
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
// 此代码版权除特别声明外的代码归作者本人Diego所有
// 源代码使用协议遵循本仓库的开源协议及附加协议
// Gitee源代码仓库https://gitee.com/diego2098/ThingsGateway
// Github源代码仓库https://github.com/kimdiego2098/ThingsGateway
// 使用文档https://diego2098.gitee.io/thingsgateway-docs/
// QQ群605534569
//------------------------------------------------------------------------------
#endregion
namespace ThingsGateway.Foundation.Serial;
/// <summary>
/// <inheritdoc cref="ISerialSessionBase"/>
/// </summary>
public interface ISerialSession : ISerialSessionBase, IClientSender, IPluginObject, ISetupConfigObject
{
/// <summary>
/// 成功打开串口
/// </summary>
ConnectedEventHandler<ISerialSession> Connected { get; set; }
/// <summary>
/// 准备连接串口的时候
/// </summary>
SerialConnectingEventHandler<ISerialSession> Connecting { get; set; }
/// <summary>
/// 连接串口
/// </summary>
/// <exception cref="Exception"></exception>
ISerialSession Connect();
}

View File

@@ -1,66 +0,0 @@
#region copyright
//------------------------------------------------------------------------------
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
// 此代码版权除特别声明外的代码归作者本人Diego所有
// 源代码使用协议遵循本仓库的开源协议及附加协议
// Gitee源代码仓库https://gitee.com/diego2098/ThingsGateway
// Github源代码仓库https://github.com/kimdiego2098/ThingsGateway
// 使用文档https://diego2098.gitee.io/thingsgateway-docs/
// QQ群605534569
//------------------------------------------------------------------------------
#endregion
using System.IO.Ports;
namespace ThingsGateway.Foundation.Serial;
/// <summary>
/// 串口连接接口。
/// </summary>
public interface ISerialSessionBase : ISenderClient, IClient, ISender, IDefaultSender, IPluginObject, IRequsetInfoSender, IConfigObject, IOnlineClient
{
/// <summary>
/// 是否允许自由调用<see cref="SetDataHandlingAdapter"/>进行赋值。
/// </summary>
bool CanSetDataHandlingAdapter { get; }
/// <summary>
/// 数据处理适配器
/// </summary>
SingleStreamDataHandlingAdapter DataHandlingAdapter { get; }
/// <summary>
/// 断开连接
/// </summary>
DisconnectEventHandler<ISerialSessionBase> Disconnected { get; set; }
/// <summary>
/// 即将断开连接(仅主动断开时有效)。
/// <para>
/// </para>
/// </summary>
DisconnectEventHandler<ISerialSessionBase> Disconnecting { get; set; }
/// <summary>
/// 主通信器
/// </summary>
SerialPort MainSerialPort { get; }
/// <summary>
/// 串口描述
/// </summary>
SerialProperty SerialProperty { get; }
/// <summary>
/// 关闭客户端。
/// </summary>
/// <param name="msg"></param>
/// <exception cref="Exception"></exception>
void Close(string msg = TouchSocketCoreUtility.Empty);
/// <summary>
/// 设置数据处理适配器
/// </summary>
/// <param name="adapter"></param>
void SetDataHandlingAdapter(SingleStreamDataHandlingAdapter adapter);
}

View File

@@ -1,388 +0,0 @@
#region copyright
//------------------------------------------------------------------------------
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
// 此代码版权除特别声明外的代码归作者本人Diego所有
// 源代码使用协议遵循本仓库的开源协议及附加协议
// Gitee源代码仓库https://gitee.com/diego2098/ThingsGateway
// Github源代码仓库https://github.com/kimdiego2098/ThingsGateway
// 使用文档https://diego2098.gitee.io/thingsgateway-docs/
// QQ群605534569
//------------------------------------------------------------------------------
#endregion
using System.IO.Ports;
namespace ThingsGateway.Foundation.Serial;
internal sealed class InternalSerialCore : SerialCore
{
}
/// <summary>
/// Serial核心
/// </summary>
public class SerialCore : IDisposable, ISender
{
/// <summary>
/// 最小缓存尺寸
/// </summary>
public int MinBufferSize { get; set; } = 1024 * 10;
/// <summary>
/// 最大缓存尺寸
/// </summary>
public int MaxBufferSize { get; set; } = 1024 * 1024 * 10;
#region
/// <summary>
/// 同步根
/// </summary>
public readonly object SyncRoot = new object();
private long m_bufferRate;
private bool m_online => m_serialPort?.IsOpen == true;
private int m_receiveBufferSize = 1024 * 10;
private ValueCounter m_receiveCounter;
private int m_sendBufferSize = 1024 * 10;
private ValueCounter m_sendCounter;
private readonly EasyLock m_semaphoreForSend = new EasyLock();
private SerialPort m_serialPort;
#endregion
/// <summary>
/// Tcp核心
/// </summary>
public SerialCore()
{
this.m_receiveCounter = new ValueCounter
{
Period = TimeSpan.FromSeconds(1),
OnPeriod = this.OnReceivePeriod
};
this.m_sendCounter = new ValueCounter
{
Period = TimeSpan.FromSeconds(1),
OnPeriod = this.OnSendPeriod
};
}
/// <summary>
/// 析构函数
/// </summary>
~SerialCore()
{
this.SafeDispose();
}
/// <inheritdoc/>
public bool CanSend => this.m_online;
/// <summary>
/// 当中断Tcp的时候。当为<see langword="true"/>时,意味着是调用<see cref="Close(string)"/>。当为<see langword="false"/>时,则是其他中断。
/// </summary>
public Action<SerialCore, bool, string> OnBreakOut { get; set; }
/// <summary>
/// 当发生异常的时候
/// </summary>
public Action<SerialCore, Exception> OnException { get; set; }
/// <summary>
/// 在线状态
/// </summary>
public bool Online { get => this.m_online; }
/// <summary>
/// UserToken
/// </summary>
public ByteBlock UserToken { get; set; }
/// <summary>
/// 当收到数据的时候
/// </summary>
public Action<SerialCore, ByteBlock> OnReceived { get; set; }
/// <summary>
/// 接收缓存池,运行时的值会根据流速自动调整
/// </summary>
public int ReceiveBufferSize
{
get => this.m_receiveBufferSize;
}
/// <summary>
/// 接收计数器
/// </summary>
public ValueCounter ReceiveCounter { get => this.m_receiveCounter; }
/// <summary>
/// 发送缓存池,运行时的值会根据流速自动调整
/// </summary>
public int SendBufferSize
{
get => this.m_sendBufferSize;
}
/// <summary>
/// 发送计数器
/// </summary>
public ValueCounter SendCounter { get => this.m_sendCounter; }
/// <summary>
/// SerialPort
/// </summary>
public SerialPort MainSerialPort { get => this.m_serialPort; }
/// <summary>
/// 开始以Iocp方式接收
/// </summary>
public virtual void BeginIocpReceive()
{
var byteBlock = BytePool.Default.GetByteBlock(this.ReceiveBufferSize);
this.UserToken = byteBlock;
byteBlock.SetLength(0);
if (this.m_serialPort.BytesToRead > 0)
{
this.m_bufferRate += 2;
this.ProcessReceived();
}
m_serialPort.DataReceived += MainSerialPort_DataReceived;
}
private void MainSerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
try
{
this.m_bufferRate = 1;
this.ProcessReceived();
}
catch (Exception ex)
{
this.PrivateBreakOut(false, ex.ToString());
}
}
/// <summary>
/// 请求关闭
/// </summary>
/// <param name="msg"></param>
public virtual void Close(string msg)
{
this.PrivateBreakOut(true, msg);
}
/// <summary>
/// 释放对象
/// </summary>
public void Dispose()
{
GC.SuppressFinalize(this);
UserToken.SafeDispose();
}
/// <summary>
/// 重置环境,并设置新的<see cref="m_serialPort"/>。
/// </summary>
/// <param name="socket"></param>
public virtual void Reset(SerialPort socket)
{
if (socket is null)
{
throw new ArgumentNullException(nameof(socket));
}
if (!socket.IsOpen)
{
throw new Exception("新的SerialPort必须在连接状态。");
}
this.Reset();
this.m_serialPort = socket;
}
/// <summary>
/// 重置环境。
/// </summary>
public virtual void Reset()
{
this.m_receiveCounter.Reset();
this.m_sendCounter.Reset();
this.m_serialPort = null;
this.OnReceived = null;
this.OnBreakOut = null;
this.UserToken = null;
this.m_bufferRate = 1;
this.m_receiveBufferSize = this.MinBufferSize;
this.m_sendBufferSize = this.MinBufferSize;
}
/// <summary>
/// 判断,当不在连接状态时触发异常。
/// </summary>
/// <exception cref="NotConnectedException"></exception>
protected void ThrowIfNotConnected()
{
if (!this.m_online)
{
throw new NotConnectedException();
}
}
/// <summary>
/// 发送数据。
/// <para>
/// 内部会根据是否启用Ssl进行直接发送还是Ssl发送。
/// </para>
/// </summary>
/// <param name="buffer"></param>
/// <param name="offset"></param>
/// <param name="length"></param>
public virtual void Send(byte[] buffer, int offset, int length)
{
this.ThrowIfNotConnected();
try
{
this.m_semaphoreForSend.Wait();
this.m_serialPort.Write(buffer, offset, length);
this.m_sendCounter.Increment(length);
}
finally
{
this.m_semaphoreForSend.Release();
}
}
/// <summary>
/// 异步发送数据。
/// </summary>
/// <param name="buffer"></param>
/// <param name="offset"></param>
/// <param name="length"></param>
/// <returns></returns>
/// <exception cref="Exception"></exception>
public virtual async Task SendAsync(byte[] buffer, int offset, int length)
{
this.ThrowIfNotConnected();
try
{
await this.m_semaphoreForSend.WaitAsync();
this.m_serialPort.Write(buffer, offset, length);
this.m_sendCounter.Increment(length);
}
finally
{
this.m_semaphoreForSend.Release();
}
}
/// <summary>
/// 当中断Tcp时。
/// </summary>
/// <param name="manual">当为<see langword="true"/>时,意味着是调用<see cref="Close(string)"/>。当为<see langword="false"/>时,则是其他中断。</param>
/// <param name="msg"></param>
protected virtual void BreakOut(bool manual, string msg)
{
this.OnBreakOut?.Invoke(this, manual, msg);
}
/// <summary>
/// 当发生异常的时候
/// </summary>
/// <param name="ex"></param>
protected virtual void Exception(Exception ex)
{
this.OnException?.Invoke(this, ex);
}
/// <summary>
/// 当收到数据的时候
/// </summary>
/// <param name="byteBlock"></param>
protected virtual void Received(ByteBlock byteBlock)
{
this.OnReceived?.Invoke(this, byteBlock);
}
private void HandleBuffer(ByteBlock byteBlock)
{
try
{
this.m_receiveCounter.Increment(byteBlock.Length);
this.Received(byteBlock);
}
catch (Exception ex)
{
this.Exception(ex);
}
finally
{
byteBlock.Dispose();
}
}
private void OnReceivePeriod(long value)
{
this.m_receiveBufferSize = Math.Max(TouchSocketUtility.HitBufferLength(value), this.MinBufferSize);
if (this.MainSerialPort != null && !MainSerialPort.IsOpen)
{
this.MainSerialPort.ReadBufferSize = this.m_receiveBufferSize;
}
}
private void OnSendPeriod(long value)
{
this.m_sendBufferSize = Math.Max(TouchSocketUtility.HitBufferLength(value), this.MinBufferSize);
if (this.MainSerialPort != null && !MainSerialPort.IsOpen)
{
this.MainSerialPort.WriteBufferSize = this.m_sendBufferSize;
}
}
private void PrivateBreakOut(bool manual, string msg)
{
lock (this.SyncRoot)
{
if (this.m_online)
{
this.BreakOut(manual, msg);
}
}
}
private void ProcessReceived()
{
if (!this.m_online)
{
UserToken?.SafeDispose();
return;
}
if (m_serialPort.BytesToRead > 0)
{
var byteBlock = UserToken;
byte[] buffer = BytePool.Default.Rent(m_serialPort.BytesToRead);
int num = m_serialPort.Read(buffer, 0, m_serialPort.BytesToRead);
byteBlock.Write(buffer, 0, num);
byteBlock.SetLength(num);
this.HandleBuffer(byteBlock);
try
{
var newByteBlock = BytePool.Default.GetByteBlock((int)Math.Min(this.ReceiveBufferSize * this.m_bufferRate, this.MaxBufferSize));
newByteBlock.SetLength(0);
UserToken = newByteBlock;
if (m_serialPort.BytesToRead > 0)
{
this.m_bufferRate += 2;
this.ProcessReceived();
}
}
catch (Exception ex)
{
this.PrivateBreakOut(false, ex.ToString());
}
}
}
}

View File

@@ -1,53 +0,0 @@
#region copyright
//------------------------------------------------------------------------------
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
// 此代码版权除特别声明外的代码归作者本人Diego所有
// 源代码使用协议遵循本仓库的开源协议及附加协议
// Gitee源代码仓库https://gitee.com/diego2098/ThingsGateway
// Github源代码仓库https://github.com/kimdiego2098/ThingsGateway
// 使用文档https://diego2098.gitee.io/thingsgateway-docs/
// QQ群605534569
//------------------------------------------------------------------------------
#endregion
using System.ComponentModel;
using System.IO.Ports;
namespace ThingsGateway.Foundation.Serial;
/// <summary>
/// 串口属性
/// </summary>
public class SerialProperty
{
/// <summary>
/// COM
/// </summary>
[Description("COM口")]
public string PortName { get; set; } = "COM1";
/// <summary>
/// 波特率
/// </summary>
[Description("波特率")]
public int BaudRate { get; set; } = 9600;
/// <summary>
/// 数据位
/// </summary>
[Description("数据位")]
public int DataBits { get; set; } = 8;
/// <summary>
/// 校验位
/// </summary>
[Description("校验位")]
public Parity Parity { get; set; } = Parity.None;
/// <summary>
/// 停止位
/// </summary>
[Description("停止位")]
public StopBits StopBits { get; set; } = StopBits.One;
/// <inheritdoc/>
public override string ToString()
{
return $"{PortName}[{BaudRate},{DataBits},{StopBits},{Parity}]";
}
}

View File

@@ -1,749 +0,0 @@
#region copyright
//------------------------------------------------------------------------------
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
// 此代码版权除特别声明外的代码归作者本人Diego所有
// 源代码使用协议遵循本仓库的开源协议及附加协议
// Gitee源代码仓库https://gitee.com/diego2098/ThingsGateway
// Github源代码仓库https://github.com/kimdiego2098/ThingsGateway
// 使用文档https://diego2098.gitee.io/thingsgateway-docs/
// QQ群605534569
//------------------------------------------------------------------------------
#endregion
using System.IO.Ports;
namespace ThingsGateway.Foundation.Serial;
/// <inheritdoc cref="SerialSessionBase"/>
public class SerialSession : SerialSessionBase
{
/// <summary>
/// 接收到数据
/// </summary>
public ReceivedEventHandler<SerialSession> Received { get; set; }
/// <inheritdoc/>
protected override Task ReceivedData(ReceivedDataEventArgs e)
{
if (this.Received != null)
{
return this.Received.Invoke(this, e);
}
return base.ReceivedData(e);
}
}
/// <summary>
/// 串口管理
/// </summary>
public class SerialSessionBase : SetupConfigObject, ISerialSession
{
static readonly Protocol SerialPort = new("SerialSession");
/// <summary>
/// 构造函数
/// </summary>
public SerialSessionBase()
{
this.Protocol = SerialPort;
}
/// <summary>
/// <inheritdoc/>
/// </summary>
/// <returns></returns>
public override string ToString()
{
return SerialProperty?.ToString();
}
#region
private DelaySender m_delaySender;
private bool m_online => MainSerialPort?.IsOpen == true;
private readonly EasyLock m_semaphore = new();
private readonly InternalSerialCore m_serialCore = new();
#endregion
#region
/// <inheritdoc/>
public ConnectedEventHandler<ISerialSession> Connected { get; set; }
/// <inheritdoc/>
public SerialConnectingEventHandler<ISerialSession> Connecting { get; set; }
/// <inheritdoc/>
public DisconnectEventHandler<ISerialSessionBase> Disconnected { get; set; }
/// <inheritdoc/>
public DisconnectEventHandler<ISerialSessionBase> Disconnecting { get; set; }
private async Task PrivateOnConnected(ConnectedEventArgs o)
{
await this.OnConnected(o);
}
/// <summary>
/// 已经建立连接
/// </summary>
/// <param name="e"></param>
protected virtual async Task OnConnected(ConnectedEventArgs e)
{
try
{
if (this.Connected != null)
{
await this.Connected.Invoke(this, e);
if (e.Handled)
{
return;
}
}
await this.PluginsManager.RaiseAsync(nameof(ITcpConnectedPlugin.OnTcpConnected), this, e);
}
catch (Exception ex)
{
this.Logger.Log(LogLevel.Error, this, $"在事件{nameof(this.Connected)}中发生错误。", ex);
}
}
private async Task PrivateOnConnecting(SerialConnectingEventArgs e)
{
if (this.CanSetDataHandlingAdapter)
{
this.SetDataHandlingAdapter(this.Config.GetValue(TouchSocketConfigExtension.TcpDataHandlingAdapterProperty).Invoke());
}
await this.OnConnecting(e);
}
/// <summary>
/// 准备连接的时候,此时并未建立连接
/// </summary>
/// <param name="e"></param>
protected virtual async Task OnConnecting(SerialConnectingEventArgs e)
{
try
{
if (this.Connecting != null)
{
await this.Connecting.Invoke(this, e);
if (e.Handled)
{
return;
}
}
await this.PluginsManager.RaiseAsync(nameof(ITcpConnectingPlugin.OnTcpConnecting), this, e);
}
catch (Exception ex)
{
this.Logger.Log(LogLevel.Error, this, $"在事件{nameof(this.OnConnecting)}中发生错误。", ex);
}
}
private async Task PrivateOnDisconnected(object obj)
{
this.m_receiver?.TryInputReceive(default, default);
await this.OnDisconnected((DisconnectEventArgs)obj);
}
/// <summary>
/// 断开连接。在客户端未设置连接状态时,不会触发
/// </summary>
/// <param name="e"></param>
protected virtual async Task OnDisconnected(DisconnectEventArgs e)
{
try
{
if (this.Disconnected != null)
{
await this.Disconnected.Invoke(this, e).ConfigureAwait(false);
if (e.Handled)
{
return;
}
}
await this.PluginsManager.RaiseAsync(nameof(ITcpDisconnectedPlugin.OnTcpDisconnected), this, e).ConfigureAwait(false);
}
catch (Exception ex)
{
this.Logger.Log(LogLevel.Error, this, $"在事件{nameof(this.Disconnected)}中发生错误。", ex);
}
}
private async Task PrivateOnDisconnecting(object obj)
{
await this.OnDisconnecting((DisconnectEventArgs)obj);
}
/// <summary>
/// 即将断开连接(仅主动断开时有效)。
/// </summary>
/// <param name="e"></param>
protected virtual async Task OnDisconnecting(DisconnectEventArgs e)
{
try
{
if (this.Disconnecting != null)
{
await this.Disconnecting.Invoke(this, e).ConfigureAwait(false);
if (e.Handled)
{
return;
}
}
await this.PluginsManager.RaiseAsync(nameof(ITcpDisconnectingPlugin.OnTcpDisconnecting), this, e).ConfigureAwait(false);
}
catch (Exception ex)
{
this.Logger.Log(LogLevel.Error, this, $"在事件{nameof(this.Disconnecting)}中发生错误。", ex);
}
}
#endregion
#region
/// <inheritdoc/>
public DateTime LastReceivedTime => this.GetSerialCore().ReceiveCounter.LastIncrement;
/// <inheritdoc/>
public DateTime LastSendTime => this.GetSerialCore().SendCounter.LastIncrement;
/// <inheritdoc/>
public virtual bool CanSetDataHandlingAdapter => true;
/// <inheritdoc/>
public SingleStreamDataHandlingAdapter DataHandlingAdapter { get; private set; }
/// <inheritdoc/>
public SerialProperty SerialProperty { get; private set; }
/// <inheritdoc/>
public SerialPort MainSerialPort { get; private set; }
/// <inheritdoc/>
public bool Online { get => this.m_online; }
/// <inheritdoc/>
public bool CanSend => this.m_online;
/// <inheritdoc/>
public Protocol Protocol { get; set; }
#endregion
#region
/// <inheritdoc/>
public virtual void Close(string msg = TouchSocketCoreUtility.Empty)
{
lock (this.GetSerialCore())
{
if (this.m_online)
{
Task.Factory.StartNew(this.PrivateOnDisconnecting, new DisconnectEventArgs(true, msg));
this.MainSerialPort.TryClose();
this.BreakOut(true, msg);
}
}
}
/// <summary>
/// <inheritdoc/>
/// </summary>
/// <param name="disposing"></param>
protected override void Dispose(bool disposing)
{
lock (this.GetSerialCore())
{
if (this.m_online)
{
Task.Factory.StartNew(this.PrivateOnDisconnecting, new DisconnectEventArgs(true, $"{nameof(Dispose)}主动断开"));
this.BreakOut(true, $"{nameof(Dispose)}主动断开");
}
}
base.Dispose(disposing);
}
#endregion
#region Connect
/// <summary>
/// 打开串口
/// </summary>
protected void Open()
{
try
{
ThrowIfDisposed();
this.m_semaphore.Wait();
if (this.m_online)
{
return;
}
if (this.DisposedValue)
{
throw new ObjectDisposedException(this.GetType().FullName);
}
if (this.Config == null)
{
throw new ArgumentNullException(nameof(this.Config), "配置文件不能为空。");
}
var serialProperty = this.Config.GetValue(SerialConfigExtension.SerialProperty) ?? throw new ArgumentNullException("串口配置不能为空。");
this.MainSerialPort.SafeDispose();
var serialPort = CreateSerial(serialProperty);
this.PrivateOnConnecting(new(serialPort)).ConfigureAwait(false).GetAwaiter().GetResult();
serialPort.Open();
this.SetSerialPort(serialPort);
this.BeginReceive();
this.PrivateOnConnected(new()).ConfigureAwait(false).GetAwaiter().GetResult();
}
finally
{
this.m_semaphore.Release();
}
}
private void BeginReceive()
{
this.GetSerialCore().BeginIocpReceive();
}
/// <inheritdoc/>
public virtual ISerialSession Connect()
{
this.Open();
return this;
}
/// <inheritdoc/>
public async Task<ISerialSession> ConnectAsync()
{
return await Task.Run(() =>
{
return this.Connect();
});
}
#endregion Connect
#region Receiver
private Receiver m_receiver;
/// <inheritdoc/>
public IReceiver CreateReceiver()
{
return this.m_receiver ??= new Receiver(this);
}
/// <inheritdoc/>
public void ClearReceiver()
{
this.m_receiver = null;
}
#endregion
private void SerialCoreBreakOut(SerialCore core, bool manual, string msg)
{
this.BreakOut(manual, msg);
}
/// <summary>
/// BreakOut。
/// </summary>
/// <param name="manual"></param>
/// <param name="msg"></param>
protected void BreakOut(bool manual, string msg)
{
lock (this.GetSerialCore())
{
if (this.m_online)
{
this.MainSerialPort.SafeDispose();
this.m_delaySender.SafeDispose();
this.DataHandlingAdapter.SafeDispose();
Task.Factory.StartNew(this.PrivateOnDisconnected, new DisconnectEventArgs(manual, msg));
}
}
}
private SerialCore GetSerialCore()
{
this.ThrowIfDisposed();
return this.m_serialCore ?? throw new ObjectDisposedException(this.GetType().Name);
}
/// <inheritdoc/>
public virtual void SetDataHandlingAdapter(SingleStreamDataHandlingAdapter adapter)
{
if (!this.CanSetDataHandlingAdapter)
{
throw new Exception($"不允许自由调用{nameof(SetDataHandlingAdapter)}进行赋值。");
}
this.SetAdapter(adapter);
}
private void PrivateHandleReceivedData(ByteBlock byteBlock, IRequestInfo requestInfo)
{
if (this.m_receiver != null)
{
if (this.m_receiver.TryInputReceive(byteBlock, requestInfo))
{
return;
}
}
this.ReceivedData(new ReceivedDataEventArgs(byteBlock, requestInfo)).GetFalseAwaitResult();
}
/// <summary>
/// 当收到适配器处理的数据时。
/// </summary>
/// <param name="e"></param>
/// <returns>如果返回<see langword="true"/>则表示数据已被处理,且不会再向下传递。</returns>
protected virtual Task ReceivedData(ReceivedDataEventArgs e)
{
return this.PluginsManager.RaiseAsync(nameof(ITcpReceivedPlugin.OnTcpReceived), this, e);
}
/// <summary>
/// 当即将发送时,如果覆盖父类方法,则不会触发插件。
/// </summary>
/// <param name="buffer">数据缓存区</param>
/// <param name="offset">偏移</param>
/// <param name="length">长度</param>
/// <returns>返回值表示是否允许发送</returns>
protected virtual async Task<bool> SendingData(byte[] buffer, int offset, int length)
{
if (this.PluginsManager.GetPluginCount(nameof(ITcpSendingPlugin.OnTcpSending)) > 0)
{
var args = new SendingEventArgs(buffer, offset, length);
await this.PluginsManager.RaiseAsync(nameof(ITcpSendingPlugin.OnTcpSending), this, args).ConfigureAwait(false);
return args.IsPermitOperation;
}
return true;
}
/// <inheritdoc/>
protected override void LoadConfig(TouchSocketConfig config)
{
this.SerialProperty = config.GetValue(SerialConfigExtension.SerialProperty);
this.Logger ??= this.Container.Resolve<ILog>();
}
/// <summary>
/// 设置适配器,该方法不会检验<see cref="CanSetDataHandlingAdapter"/>的值。
/// </summary>
/// <param name="adapter"></param>
protected void SetAdapter(SingleStreamDataHandlingAdapter adapter)
{
this.ThrowIfDisposed();
if (adapter is null)
{
throw new ArgumentNullException(nameof(adapter));
}
if (this.Config != null)
{
adapter.Config(this.Config);
}
adapter.Logger = this.Logger;
adapter.OnLoaded(this);
adapter.ReceivedCallBack = this.PrivateHandleReceivedData;
adapter.SendCallBack = this.DefaultSend;
adapter.SendAsyncCallBack = this.DefaultSendAsync;
this.DataHandlingAdapter = adapter;
}
private static SerialPort CreateSerial(SerialProperty serialProperty)
{
SerialPort serialPort = new(serialProperty.PortName, serialProperty.BaudRate, serialProperty.Parity, serialProperty.DataBits, serialProperty.StopBits)
{
DtrEnable = true,
RtsEnable = true
};
return serialPort;
}
#region
#region
/// <summary>
/// <inheritdoc/>
/// </summary>
/// <param name="requestInfo"></param>
/// <exception cref="NotConnectedException"></exception>
/// <exception cref="OverlengthException"></exception>
/// <exception cref="Exception"></exception>
public void Send(IRequestInfo requestInfo)
{
if (this.DisposedValue)
{
return;
}
if (this.DataHandlingAdapter == null)
{
throw new ArgumentNullException(nameof(this.DataHandlingAdapter), TouchSocketResource.NullDataAdapter.GetDescription());
}
if (!this.DataHandlingAdapter.CanSendRequestInfo)
{
throw new NotSupportedException($"当前适配器不支持对象发送。");
}
this.DataHandlingAdapter.SendInput(requestInfo);
}
/// <summary>
/// <inheritdoc/>
/// </summary>
/// <param name="buffer"><inheritdoc/></param>
/// <param name="offset"><inheritdoc/></param>
/// <param name="length"><inheritdoc/></param>
/// <exception cref="NotConnectedException"><inheritdoc/></exception>
/// <exception cref="OverlengthException"><inheritdoc/></exception>
/// <exception cref="Exception"><inheritdoc/></exception>
public virtual void Send(byte[] buffer, int offset, int length)
{
if (this.DataHandlingAdapter == null)
{
throw new ArgumentNullException(nameof(this.DataHandlingAdapter), TouchSocketResource.NullDataAdapter.GetDescription());
}
this.DataHandlingAdapter.SendInput(buffer, offset, length);
}
/// <summary>
/// <inheritdoc/>
/// </summary>
/// <param name="transferBytes"><inheritdoc/></param>
/// <exception cref="NotConnectedException"><inheritdoc/></exception>
/// <exception cref="OverlengthException"><inheritdoc/></exception>
/// <exception cref="Exception"><inheritdoc/></exception>
public virtual void Send(IList<ArraySegment<byte>> transferBytes)
{
if (this.DataHandlingAdapter == null)
{
throw new ArgumentNullException(nameof(this.DataHandlingAdapter), TouchSocketResource.NullDataAdapter.GetDescription());
}
if (this.DataHandlingAdapter.CanSplicingSend)
{
this.DataHandlingAdapter.SendInput(transferBytes);
}
else
{
var length = 0;
foreach (var item in transferBytes)
{
length += item.Count;
}
using (var byteBlock = new ByteBlock(length))
{
foreach (var item in transferBytes)
{
byteBlock.Write(item.Array, item.Offset, item.Count);
}
this.DataHandlingAdapter.SendInput(byteBlock.Buffer, 0, byteBlock.Len);
}
}
}
#endregion
#region
/// <summary>
/// <inheritdoc/>
/// </summary>
/// <param name="buffer"></param>
/// <param name="offset"></param>
/// <param name="length"></param>
/// <exception cref="NotConnectedException"></exception>
/// <exception cref="OverlengthException"></exception>
/// <exception cref="Exception"></exception>
public virtual Task SendAsync(byte[] buffer, int offset, int length)
{
this.ThrowIfDisposed();
if (this.DataHandlingAdapter == null)
{
throw new ArgumentNullException(nameof(this.DataHandlingAdapter), TouchSocketResource.NullDataAdapter.GetDescription());
}
return this.DataHandlingAdapter.SendInputAsync(buffer, offset, length);
}
/// <summary>
/// <inheritdoc/>
/// </summary>
/// <param name="requestInfo"></param>
/// <exception cref="NotConnectedException"></exception>
/// <exception cref="OverlengthException"></exception>
/// <exception cref="Exception"></exception>
public virtual Task SendAsync(IRequestInfo requestInfo)
{
this.ThrowIfDisposed();
if (this.DataHandlingAdapter == null)
{
throw new ArgumentNullException(nameof(this.DataHandlingAdapter), TouchSocketResource.NullDataAdapter.GetDescription());
}
if (!this.DataHandlingAdapter.CanSendRequestInfo)
{
throw new NotSupportedException($"当前适配器不支持对象发送。");
}
return this.DataHandlingAdapter.SendInputAsync(requestInfo);
}
/// <summary>
/// <inheritdoc/>
/// </summary>
/// <param name="transferBytes"></param>
/// <returns></returns>
/// <exception cref="ArgumentNullException"></exception>
public virtual Task SendAsync(IList<ArraySegment<byte>> transferBytes)
{
this.ThrowIfDisposed();
if (this.DataHandlingAdapter == null)
{
throw new ArgumentNullException(nameof(this.DataHandlingAdapter), TouchSocketResource.NullDataAdapter.GetDescription());
}
if (this.DataHandlingAdapter.CanSplicingSend)
{
return this.DataHandlingAdapter.SendInputAsync(transferBytes);
}
else
{
var length = 0;
foreach (var item in transferBytes)
{
length += item.Count;
}
using (var byteBlock = new ByteBlock(length))
{
foreach (var item in transferBytes)
{
byteBlock.Write(item.Array, item.Offset, item.Count);
}
return this.DataHandlingAdapter.SendInputAsync(byteBlock.Buffer, 0, byteBlock.Len);
}
}
}
#endregion
/// <inheritdoc/>
public void DefaultSend(byte[] buffer, int offset, int length)
{
if (this.SendingData(buffer, offset, length).GetFalseAwaitResult())
{
if (this.m_delaySender != null)
{
this.m_delaySender.Send(new QueueDataBytes(buffer, offset, length));
return;
}
this.GetSerialCore().Send(buffer, offset, length);
}
}
/// <inheritdoc/>
public async Task DefaultSendAsync(byte[] buffer, int offset, int length)
{
if (await this.SendingData(buffer, offset, length))
{
await this.GetSerialCore().SendAsync(buffer, offset, length);
}
}
#endregion
#region
private void SetSerialPort(SerialPort serialPort)
{
if (serialPort == null)
{
return;
}
this.MainSerialPort = serialPort;
this.SerialProperty ??= new();
this.SerialProperty.Parity = serialPort.Parity;
this.SerialProperty.PortName = serialPort.PortName;
this.SerialProperty.StopBits = serialPort.StopBits;
this.SerialProperty.DataBits = serialPort.DataBits;
this.SerialProperty.BaudRate = serialPort.BaudRate;
var delaySenderOption = this.Config.GetValue(TouchSocketConfigExtension.DelaySenderProperty);
if (delaySenderOption != null)
{
this.m_delaySender = new DelaySender(delaySenderOption, this.MainSerialPort.AbsoluteSend);
}
this.m_serialCore.Reset(serialPort);
this.m_serialCore.OnReceived = this.HandleReceived;
this.m_serialCore.OnBreakOut = this.SerialCoreBreakOut;
if (this.Config.GetValue(TouchSocketConfigExtension.MinBufferSizeProperty) is int minValue)
{
this.m_serialCore.MinBufferSize = minValue;
}
if (this.Config.GetValue(TouchSocketConfigExtension.MaxBufferSizeProperty) is int maxValue)
{
this.m_serialCore.MaxBufferSize = maxValue;
}
}
private void HandleReceived(SerialCore core, ByteBlock byteBlock)
{
try
{
if (this.DisposedValue)
{
return;
}
if (this.ReceivingData(byteBlock).GetFalseAwaitResult())
{
return;
}
if (this.DataHandlingAdapter == null)
{
this.Logger.Error(this, TouchSocketResource.NullDataAdapter.GetDescription());
return;
}
this.DataHandlingAdapter.ReceivedInput(byteBlock);
}
catch (Exception ex)
{
this.Logger.Log(LogLevel.Error, this, "在处理数据时发生错误", ex);
}
}
/// <summary>
/// 当收到原始数据
/// </summary>
/// <param name="byteBlock"></param>
/// <returns>如果返回<see langword="true"/>则表示数据已被处理,且不会再向下传递。</returns>
protected virtual Task<bool> ReceivingData(ByteBlock byteBlock)
{
if (this.PluginsManager.GetPluginCount(nameof(ITcpReceivingPlugin.OnTcpReceiving)) > 0)
{
return this.PluginsManager.RaiseAsync(nameof(ITcpReceivingPlugin.OnTcpReceiving), this, new ByteBlockEventArgs(byteBlock));
}
return Task.FromResult(false);
}
#endregion
}

View File

@@ -20,6 +20,5 @@ global using System.Threading.Tasks;
global using ThingsGateway.Foundation.Core;
global using ThingsGateway.Foundation.Http;
global using ThingsGateway.Foundation.Rpc;
global using ThingsGateway.Foundation.Serial;
global using ThingsGateway.Foundation.SerialPorts;
global using ThingsGateway.Foundation.Sockets;

View File

@@ -15,7 +15,7 @@ namespace ThingsGateway.Foundation.Core
/// <summary>
/// 具有设置配置的对象接口
/// </summary>
public interface ISetupConfigObject : IConfigObject, IPluginObject
public interface ISetupConfigObject : IConfigObject, IPluginObject, IResolverObject
{
/// <summary>
/// 配置设置项
@@ -23,5 +23,12 @@ namespace ThingsGateway.Foundation.Core
/// <param name="config"></param>
/// <exception cref="Exception"></exception>
void Setup(TouchSocketConfig config);
/// <summary>
/// 异步配置设置项
/// </summary>
/// <param name="config"></param>
/// <returns></returns>
Task SetupAsync(TouchSocketConfig config);
}
}

View File

@@ -23,10 +23,10 @@ namespace ThingsGateway.Foundation.Core
public override TouchSocketConfig Config => this.m_config;
/// <inheritdoc/>
public IContainer Container { get; private set; }
public IResolver Resolver { get; private set; }
/// <inheritdoc/>
public IPluginsManager PluginsManager { get; private set; }
public IPluginManager PluginManager { get; private set; }
/// <inheritdoc/>
public void Setup(TouchSocketConfig config)
@@ -40,11 +40,27 @@ namespace ThingsGateway.Foundation.Core
this.BuildConfig(config);
this.PluginsManager?.Raise(nameof(ILoadingConfigPlugin.OnLoadingConfig), this, new ConfigEventArgs(config));
this.PluginManager?.Raise(nameof(ILoadingConfigPlugin.OnLoadingConfig), this, new ConfigEventArgs(config));
this.LoadConfig(this.Config);
this.PluginsManager?.Raise(nameof(ILoadedConfigPlugin.OnLoadedConfig), this, new ConfigEventArgs(config));
this.PluginManager?.Raise(nameof(ILoadedConfigPlugin.OnLoadedConfig), this, new ConfigEventArgs(config));
}
/// <inheritdoc/>
public async Task SetupAsync(TouchSocketConfig config)
{
if (config == null)
{
throw new ArgumentNullException(nameof(config));
}
this.ThrowIfDisposed();
this.BuildConfig(config);
await this.PluginManager.RaiseAsync(nameof(ILoadingConfigPlugin.OnLoadingConfig), this, new ConfigEventArgs(config)).ConfigureFalseAwait();
this.LoadConfig(config);
//return EasyTask.CompletedTask;
await this.PluginManager.RaiseAsync(nameof(ILoadedConfigPlugin.OnLoadedConfig), this, new ConfigEventArgs(config)).ConfigureFalseAwait();
}
/// <summary>
/// 加载配置
/// </summary>
@@ -56,47 +72,48 @@ namespace ThingsGateway.Foundation.Core
private void BuildConfig(TouchSocketConfig config)
{
this.m_config = config;
this.m_config = config ?? throw new ArgumentNullException(nameof(config));
if (!config.TryGetValue(TouchSocketCoreConfigExtension.ContainerProperty, out var container))
if (!config.TryGetValue(TouchSocketCoreConfigExtension.ResolverProperty, out var resolver))
{
container = new Container();
if (!config.TryGetValue(TouchSocketCoreConfigExtension.RegistratorProperty, out var registrator))
{
registrator = new Container();
}
if (!registrator.IsRegistered(typeof(ILog)))
{
registrator.RegisterSingleton<ILog>(new LoggerGroup());
}
if (config.GetValue(TouchSocketCoreConfigExtension.ConfigureContainerProperty) is Action<IRegistrator> actionContainer)
{
actionContainer.Invoke(registrator);
}
resolver = registrator.BuildResolver();
}
if (!container.IsRegistered(typeof(ILog)))
IPluginManager pluginManager;
if ((!this.Config.GetValue(TouchSocketCoreConfigExtension.NewPluginManagerProperty)) && resolver.IsRegistered<IPluginManager>())
{
container.RegisterSingleton<ILog, LoggerGroup>();
}
if (!(config.GetValue(TouchSocketCoreConfigExtension.PluginsManagerProperty) is IPluginsManager pluginsManager))
{
pluginsManager = new PluginsManager(container);
}
if (container.IsRegistered(typeof(IPluginsManager)))
{
pluginsManager = container.Resolve<IPluginsManager>();
pluginManager = resolver.Resolve<IPluginManager>();
}
else
{
container.RegisterSingleton<IPluginsManager>(pluginsManager);
pluginManager = new PluginManager(resolver);
}
if (config.GetValue(TouchSocketCoreConfigExtension.ConfigureContainerProperty) is Action<IContainer> actionContainer)
if (this.Config.GetValue(TouchSocketCoreConfigExtension.ConfigurePluginsProperty) is Action<IPluginManager> actionPluginManager)
{
actionContainer.Invoke(container);
pluginManager.Enable = true;
actionPluginManager.Invoke(pluginManager);
}
if (config.GetValue(TouchSocketCoreConfigExtension.ConfigurePluginsProperty) is Action<IPluginsManager> actionPluginsManager)
{
pluginsManager.Enable = true;
actionPluginsManager.Invoke(pluginsManager);
}
this.Logger ??= resolver.Resolve<ILog>();
this.Logger ??= container.Resolve<ILog>();
this.Container = container;
this.PluginsManager = pluginsManager;
this.PluginManager = pluginManager;
this.Resolver = resolver;
}
}
}

View File

@@ -35,14 +35,14 @@ namespace ThingsGateway.Foundation.Core
/// <summary>
/// 配置插件。
/// </summary>
public static readonly DependencyProperty<Action<IPluginsManager>> ConfigurePluginsProperty =
DependencyProperty<Action<IPluginsManager>>.Register("ConfigurePlugins", null);
public static readonly DependencyProperty<Action<IPluginManager>> ConfigurePluginsProperty =
DependencyProperty<Action<IPluginManager>>.Register("ConfigurePlugins", null);
/// <summary>
/// 容器
/// 是否使用新插件管理器。
/// </summary>
public static readonly DependencyProperty<IPluginsManager> PluginsManagerProperty =
DependencyProperty<IPluginsManager>.Register("PluginsManager", null);
public static readonly DependencyProperty<bool> NewPluginManagerProperty =
DependencyProperty<bool>.Register("NewPluginManager", false);
/// <summary>
/// 配置插件。
@@ -50,7 +50,7 @@ namespace ThingsGateway.Foundation.Core
/// <param name="config"></param>
/// <param name="value"></param>
/// <returns></returns>
public static TouchSocketConfig ConfigurePlugins(this TouchSocketConfig config, Action<IPluginsManager> value)
public static TouchSocketConfig ConfigurePlugins(this TouchSocketConfig config, Action<IPluginManager> value)
{
if (config.TryGetValue(ConfigurePluginsProperty, out var action))
{
@@ -64,15 +64,19 @@ namespace ThingsGateway.Foundation.Core
return config;
}
/// <summary>
/// 使用插件
/// 使用新的插件管理器
/// <para>
/// 一般的,当在容器<see cref="IContainer"/>中注入<see cref="IPluginManager"/>时。会使用容器中的<see cref="IPluginManager"/>。
/// 但是有时候,我们希望个别配置能够独立使用插件管理器。所以可以使用此配置。
/// </para>
/// </summary>
/// <param name="config"></param>
/// <param name="value"></param>
/// <returns></returns>
public static TouchSocketConfig SetPluginsManager(this TouchSocketConfig config, IPluginsManager value)
public static TouchSocketConfig UseNewPluginManager(this TouchSocketConfig config)
{
config.SetValue(PluginsManagerProperty, value);
config.SetValue(NewPluginManagerProperty, true);
return config;
}
@@ -83,14 +87,21 @@ namespace ThingsGateway.Foundation.Core
/// <summary>
/// 配置容器注入。
/// </summary>
public static readonly DependencyProperty<Action<IContainer>> ConfigureContainerProperty =
DependencyProperty<Action<IContainer>>.Register("ConfigureContainer", null);
public static readonly DependencyProperty<Action<IRegistrator>> ConfigureContainerProperty =
DependencyProperty<Action<IRegistrator>>.Register("ConfigureContainer", null);
/// <summary>
/// 容器
/// 容器注册
/// </summary>
public static readonly DependencyProperty<IContainer> ContainerProperty =
DependencyProperty<IContainer>.Register("Container", null);
public static readonly DependencyProperty<IRegistrator> RegistratorProperty =
DependencyProperty<IRegistrator>.Register("Registrator", null);
/// <summary>
/// 容器提供者
/// </summary>
public static readonly DependencyProperty<IResolver> ResolverProperty =
DependencyProperty<IResolver>.Register("Resolver", null);
/// <summary>
/// 配置容器注入。
@@ -98,7 +109,7 @@ namespace ThingsGateway.Foundation.Core
/// <param name="config"></param>
/// <param name="value"></param>
/// <returns></returns>
public static TouchSocketConfig ConfigureContainer(this TouchSocketConfig config, Action<IContainer> value)
public static TouchSocketConfig ConfigureContainer(this TouchSocketConfig config, Action<IRegistrator> value)
{
if (config.TryGetValue(ConfigureContainerProperty, out var action))
{
@@ -112,15 +123,28 @@ namespace ThingsGateway.Foundation.Core
return config;
}
/// <summary>
/// 设置容器。
/// 设置<see cref="IResolver"/>
/// </summary>
/// <param name="config"></param>
/// <param name="value"></param>
/// <returns></returns>
public static TouchSocketConfig SetContainer(this TouchSocketConfig config, IContainer value)
public static TouchSocketConfig SetResolver(this TouchSocketConfig config, IResolver value)
{
config.SetValue(ContainerProperty, value);
config.SetValue(ResolverProperty, value);
return config;
}
/// <summary>
/// 设置<see cref="IRegistrator"/>
/// </summary>
/// <param name="config"></param>
/// <param name="value"></param>
/// <returns></returns>
public static TouchSocketConfig SetRegistrator(this TouchSocketConfig config, IRegistrator value)
{
config.SetValue(RegistratorProperty, value);
return config;
}

View File

@@ -1,15 +1,3 @@
#region copyright
//------------------------------------------------------------------------------
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
// 此代码版权除特别声明外的代码归作者本人Diego所有
// 源代码使用协议遵循本仓库的开源协议及附加协议
// Gitee源代码仓库https://gitee.com/diego2098/ThingsGateway
// Github源代码仓库https://github.com/kimdiego2098/ThingsGateway
// 使用文档https://diego2098.gitee.io/thingsgateway-docs/
// QQ群605534569
//------------------------------------------------------------------------------
#endregion
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在XREF结尾的命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
@@ -21,7 +9,6 @@
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
namespace ThingsGateway.Foundation.Core
{
@@ -36,7 +23,6 @@ namespace ThingsGateway.Foundation.Core
/// </summary>
public DependencyInjectAttribute()
{
}
/// <summary>

View File

@@ -1,15 +1,3 @@
#region copyright
//------------------------------------------------------------------------------
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
// 此代码版权除特别声明外的代码归作者本人Diego所有
// 源代码使用协议遵循本仓库的开源协议及附加协议
// Gitee源代码仓库https://gitee.com/diego2098/ThingsGateway
// Github源代码仓库https://github.com/kimdiego2098/ThingsGateway
// 使用文档https://diego2098.gitee.io/thingsgateway-docs/
// QQ群605534569
//------------------------------------------------------------------------------
#endregion
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在XREF结尾的命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
@@ -21,8 +9,7 @@
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
using System.Collections;
using System.Collections.Concurrent;
using System.Reflection;
@@ -31,53 +18,66 @@ namespace ThingsGateway.Foundation.Core
/// <summary>
/// IOC容器
/// </summary>
public class Container : IContainer
public sealed class Container : IContainer
{
private readonly ConcurrentDictionary<string, DependencyDescriptor> m_registrations = new ConcurrentDictionary<string, DependencyDescriptor>();
/// <summary>
/// 返回迭代
/// IOC容
/// </summary>
/// <returns></returns>
public IEnumerator<DependencyDescriptor> GetEnumerator()
public Container()
{
return this.m_registrations.Values.GetEnumerator();
this.RegisterSingleton<IResolver>(this);
this.RegisterSingleton<IServiceProvider>(this);
}
/// <summary>
/// <inheritdoc/>
/// </summary>
/// <param name="fromType"></param>
/// <param name="key"></param>
/// <returns></returns>
public bool IsRegistered(Type fromType, string key = "")
public IResolver BuildResolver()
{
return fromType == typeof(IContainer) || this.m_registrations.ContainsKey($"{fromType.FullName}{key}");
return this;
}
/// <summary>
/// <inheritdoc/>
/// </summary>
/// <param name="descriptor"></param>
/// <param name="key"></param>
public void Register(DependencyDescriptor descriptor, string key = "")
public IEnumerable<DependencyDescriptor> GetDescriptors()
{
return this.m_registrations.Values;
}
/// <inheritdoc/>
public object GetService(Type serviceType)
{
return this.Resolve(serviceType);
}
/// <inheritdoc/>
public bool IsRegistered(Type fromType, string key)
{
return this.m_registrations.ContainsKey($"{fromType.FullName}{key}");
}
/// <inheritdoc/>
public bool IsRegistered(Type fromType)
{
return this.m_registrations.ContainsKey(fromType.FullName);
}
/// <inheritdoc/>
public void Register(DependencyDescriptor descriptor, string key)
{
var k = $"{descriptor.FromType.FullName}{key}";
this.m_registrations.AddOrUpdate(k, descriptor, (k, v) => { return descriptor; });
}
/// <summary>
/// <inheritdoc/>
/// </summary>
/// <param name="fromType"></param>
/// <param name="key"></param>
/// <returns></returns>
public object Resolve(Type fromType, string key = "")
public void Register(DependencyDescriptor descriptor)
{
var k = descriptor.FromType.FullName;
this.m_registrations.AddOrUpdate(k, descriptor, (k, v) => { return descriptor; });
}
/// <inheritdoc/>
public object Resolve(Type fromType, string key)
{
if (fromType == typeof(IContainer))
{
return this;
}
string k;
DependencyDescriptor descriptor;
if (fromType.IsGenericType)
@@ -160,17 +160,105 @@ namespace ThingsGateway.Foundation.Core
}
}
/// <summary>
/// <inheritdoc/>
/// </summary>
/// <param name="descriptor"></param>
/// <param name="key"></param>
public void Unregister(DependencyDescriptor descriptor, string key = "")
public object Resolve(Type fromType)
{
string k;
DependencyDescriptor descriptor;
if (fromType.IsGenericType)
{
var type = fromType.GetGenericTypeDefinition();
k = type.FullName;
if (this.m_registrations.TryGetValue(k, out descriptor))
{
if (descriptor.ImplementationFactory != null)
{
return descriptor.ImplementationFactory.Invoke(this);
}
if (descriptor.Lifetime == Lifetime.Singleton)
{
if (descriptor.ToInstance != null)
{
return descriptor.ToInstance;
}
lock (descriptor)
{
if (descriptor.ToInstance != null)
{
return descriptor.ToInstance;
}
else
{
if (descriptor.ToType.IsGenericType)
{
return (descriptor.ToInstance = this.Create(descriptor, descriptor.ToType.MakeGenericType(fromType.GetGenericArguments())));
}
else
{
return descriptor.ToInstance = this.Create(descriptor, descriptor.ToType);
}
}
}
}
if (descriptor.ToType.IsGenericType)
{
return this.Create(descriptor, descriptor.ToType.MakeGenericType(fromType.GetGenericArguments()));
}
else
{
return this.Create(descriptor, descriptor.ToType);
}
}
}
k = fromType.FullName;
if (this.m_registrations.TryGetValue(k, out descriptor))
{
if (descriptor.ImplementationFactory != null)
{
return descriptor.ImplementationFactory.Invoke(this);
}
if (descriptor.Lifetime == Lifetime.Singleton)
{
if (descriptor.ToInstance != null)
{
return descriptor.ToInstance;
}
lock (descriptor)
{
return descriptor.ToInstance ??= this.Create(descriptor, descriptor.ToType);
}
}
return this.Create(descriptor, descriptor.ToType);
}
else
{
if (fromType.IsPrimitive || fromType == typeof(string))
{
return default;
}
else
{
throw new Exception(TouchSocketCoreResource.UnregisteredType.GetDescription(fromType));
}
}
}
/// <inheritdoc/>
public void Unregister(DependencyDescriptor descriptor, string key)
{
var k = $"{descriptor.FromType.FullName}{key}";
this.m_registrations.TryRemove(k, out _);
}
/// <inheritdoc/>
public void Unregister(DependencyDescriptor descriptor)
{
var k = descriptor.FromType.FullName;
this.m_registrations.TryRemove(k, out _);
}
private object Create(DependencyDescriptor descriptor, Type toType)
{
var ctor = toType.GetConstructors().FirstOrDefault(x => x.IsDefined(typeof(DependencyInjectAttribute), true));
@@ -275,10 +363,5 @@ namespace ThingsGateway.Foundation.Core
descriptor.OnResolved?.Invoke(instance);
return instance;
}
IEnumerator IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
}
}

View File

@@ -0,0 +1,735 @@
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在XREF结尾的命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// API首页http://rrqm_home.gitee.io/touchsocket/
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在XREF结尾的命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// API首页http://rrqm_home.gitee.io/touchsocket/
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
using System.Data;
using System.Reflection;
namespace ThingsGateway.Foundation.Core
{
/// <summary>
/// ContainerExtension
/// </summary>
public static class ContainerExtension
{
#region RegisterSingleton
/// <summary>
/// 注册单例
/// </summary>
/// <typeparam name="TFrom"></typeparam>
/// <typeparam name="TTo"></typeparam>
/// <param name="registrator"></param>
/// <param name="instance"></param>
/// <returns></returns>
public static IRegistrator RegisterSingleton<TFrom, TTo>(this IRegistrator registrator, TTo instance)
where TFrom : class
where TTo : class, TFrom
{
RegisterSingleton(registrator, typeof(TFrom), instance);
return registrator;
}
/// <summary>
/// 注册单例
/// </summary>
/// <param name="registrator"></param>
/// <param name="instance"></param>
/// <returns></returns>
public static IRegistrator RegisterSingleton(this IRegistrator registrator, object instance)
{
if (instance is null)
{
throw new ArgumentNullException(nameof(instance));
}
RegisterSingleton(registrator, instance.GetType(), instance);
return registrator;
}
/// <summary>
/// 注册单例
/// </summary>
/// <param name="registrator"></param>
/// <param name="fromType"></param>
/// <returns></returns>
/// <exception cref="ArgumentNullException"></exception>
public static IRegistrator RegisterSingleton(this IRegistrator registrator, Type fromType)
{
if (fromType is null)
{
throw new ArgumentNullException(nameof(fromType));
}
RegisterSingleton(registrator, fromType, fromType);
return registrator;
}
/// <summary>
/// 注册单例
/// </summary>
/// <typeparam name="TFrom"></typeparam>
/// <typeparam name="TTo"></typeparam>
/// <param name="registrator"></param>
/// <param name="key"></param>
/// <param name="instance"></param>
/// <returns></returns>
public static IRegistrator RegisterSingleton<TFrom, TTo>(this IRegistrator registrator, string key, TTo instance)
where TFrom : class
where TTo : class, TFrom
{
RegisterSingleton(registrator, typeof(TFrom), instance, key);
return registrator;
}
/// <summary>
/// 注册单例
/// </summary>
/// <param name="registrator"></param>
/// <param name="fromType"></param>
/// <param name="instance"></param>
/// <param name="key"></param>
/// <returns></returns>
public static IRegistrator RegisterSingleton(this IRegistrator registrator, Type fromType, object instance, string key)
{
registrator.Register(new DependencyDescriptor(fromType, instance), key);
return registrator;
}
/// <summary>
/// 注册单例
/// </summary>
/// <param name="registrator"></param>
/// <param name="fromType"></param>
/// <param name="instance"></param>
/// <returns></returns>
public static IRegistrator RegisterSingleton(this IRegistrator registrator, Type fromType, object instance)
{
registrator.Register(new DependencyDescriptor(fromType, instance));
return registrator;
}
/// <summary>
/// 注册单例
/// </summary>
/// <typeparam name="TFrom"></typeparam>
/// <param name="registrator"></param>
/// <param name="instance"></param>
/// <param name="key"></param>
/// <returns></returns>
public static IRegistrator RegisterSingleton<TFrom>(this IRegistrator registrator, object instance, string key)
{
registrator.Register(new DependencyDescriptor(typeof(TFrom), instance), key);
return registrator;
}
/// <summary>
/// 注册单例
/// </summary>
/// <typeparam name="TFrom"></typeparam>
/// <param name="registrator"></param>
/// <param name="instance"></param>
/// <returns></returns>
public static IRegistrator RegisterSingleton<TFrom>(this IRegistrator registrator, object instance)
{
registrator.Register(new DependencyDescriptor(typeof(TFrom), instance));
return registrator;
}
/// <summary>
/// 注册单例
/// </summary>
/// <param name="registrator"></param>
/// <param name="instance"></param>
/// <param name="key"></param>
/// <returns></returns>
public static IRegistrator RegisterSingleton(this IRegistrator registrator, object instance, string key)
{
registrator.Register(new DependencyDescriptor(instance.GetType(), instance), key);
return registrator;
}
/// <summary>
/// 注册单例
/// </summary>
/// <typeparam name="TFrom"></typeparam>
/// <param name="registrator"></param>
/// <returns></returns>
public static IRegistrator RegisterSingleton<TFrom>(this IRegistrator registrator)
{
registrator.Register(new DependencyDescriptor(typeof(TFrom), typeof(TFrom), Lifetime.Singleton));
return registrator;
}
/// <summary>
/// 注册单例
/// </summary>
/// <typeparam name="TFrom"></typeparam>
/// <param name="registrator"></param>
/// <param name="key"></param>
/// <returns></returns>
public static IRegistrator RegisterSingleton<TFrom>(this IRegistrator registrator, string key)
{
registrator.Register(new DependencyDescriptor(typeof(TFrom), typeof(TFrom), Lifetime.Singleton), key);
return registrator;
}
/// <summary>
/// 注册单例
/// </summary>
/// <param name="registrator"></param>
/// <param name="fromType"></param>
/// <param name="toType"></param>
/// <returns></returns>
public static IRegistrator RegisterSingleton(this IRegistrator registrator, Type fromType, Type toType)
{
registrator.Register(new DependencyDescriptor(fromType, toType, Lifetime.Singleton));
return registrator;
}
/// <summary>
/// 注册单例
/// </summary>
/// <param name="registrator"></param>
/// <param name="fromType"></param>
/// <param name="toType"></param>
/// <param name="key"></param>
/// <returns></returns>
public static IRegistrator RegisterSingleton(this IRegistrator registrator, Type fromType, Type toType, string key)
{
registrator.Register(new DependencyDescriptor(fromType, toType, Lifetime.Singleton), key);
return registrator;
}
/// <summary>
/// 注册单例
/// </summary>
/// <param name="registrator"></param>
/// <param name="func"></param>
/// <returns></returns>
public static IRegistrator RegisterSingleton<TFrom>(this IRegistrator registrator, Func<IResolver, object> func)
{
registrator.Register(new DependencyDescriptor(typeof(TFrom), Lifetime.Singleton)
{
ImplementationFactory = func
});
return registrator;
}
/// <summary>
/// 注册单例
/// </summary>
/// <param name="registrator"></param>
/// <param name="func"></param>
/// <param name="key"></param>
/// <returns></returns>
public static IRegistrator RegisterSingleton<TFrom>(this IRegistrator registrator, Func<IResolver, object> func, string key)
{
registrator.Register(new DependencyDescriptor(typeof(TFrom), Lifetime.Singleton)
{
ImplementationFactory = func
}, key);
return registrator;
}
/// <summary>
/// 注册单例
/// </summary>
/// <param name="registrator"></param>
/// <param name="fromType"></param>
/// <param name="func"></param>
/// <returns></returns>
public static IRegistrator RegisterSingleton(this IRegistrator registrator, Type fromType, Func<IResolver, object> func)
{
registrator.Register(new DependencyDescriptor(fromType, Lifetime.Singleton)
{
ImplementationFactory = func
});
return registrator;
}
/// <summary>
/// 注册单例
/// </summary>
/// <param name="registrator"></param>
/// <param name="fromType"></param>
/// <param name="func"></param>
/// <param name="key"></param>
/// <returns></returns>
public static IRegistrator RegisterSingleton(this IRegistrator registrator, Type fromType, Func<IResolver, object> func, string key)
{
registrator.Register(new DependencyDescriptor(fromType, Lifetime.Singleton)
{
ImplementationFactory = func
}, key);
return registrator;
}
/// <summary>
/// 注册单例
/// </summary>
/// <typeparam name="TFrom"></typeparam>
/// <typeparam name="TTO"></typeparam>
/// <param name="registrator"></param>
/// <returns></returns>
public static IRegistrator RegisterSingleton<TFrom, TTO>(this IRegistrator registrator)
where TFrom : class
where TTO : class, TFrom
{
RegisterSingleton(registrator, typeof(TFrom), typeof(TTO));
return registrator;
}
/// <summary>
/// 注册单例
/// </summary>
/// <typeparam name="TFrom"></typeparam>
/// <typeparam name="TTO"></typeparam>
/// <param name="registrator"></param>
/// <param name="key"></param>
/// <returns></returns>
public static IRegistrator RegisterSingleton<TFrom, TTO>(this IRegistrator registrator, string key)
where TFrom : class
where TTO : class, TFrom
{
RegisterSingleton(registrator, typeof(TFrom), typeof(TTO), key);
return registrator;
}
#endregion RegisterSingleton
#region Transient
/// <summary>
/// 注册临时映射
/// </summary>
/// <typeparam name="TFrom"></typeparam>
/// <typeparam name="TTO"></typeparam>
/// <param name="registrator"></param>
/// <returns></returns>
public static IRegistrator RegisterTransient<TFrom, TTO>(this IRegistrator registrator)
where TFrom : class
where TTO : class, TFrom
{
RegisterTransient(registrator, typeof(TFrom), typeof(TTO));
return registrator;
}
/// <summary>
/// 注册临时映射
/// </summary>
/// <typeparam name="TFrom"></typeparam>
/// <param name="registrator"></param>
/// <returns></returns>
public static IRegistrator RegisterTransient<TFrom>(this IRegistrator registrator)
where TFrom : class
{
RegisterTransient(registrator, typeof(TFrom), typeof(TFrom));
return registrator;
}
/// <summary>
/// 注册临时映射
/// </summary>
/// <typeparam name="TFrom"></typeparam>
/// <param name="registrator"></param>
/// <param name="key"></param>
/// <returns></returns>
public static IRegistrator RegisterTransient<TFrom>(this IRegistrator registrator, string key)
where TFrom : class
{
RegisterTransient(registrator, typeof(TFrom), typeof(TFrom), key);
return registrator;
}
/// <summary>
/// 注册临时映射
/// </summary>
/// <typeparam name="TFrom"></typeparam>
/// <typeparam name="TTO"></typeparam>
/// <param name="registrator"></param>
/// <param name="key"></param>
/// <returns></returns>
public static IRegistrator RegisterTransient<TFrom, TTO>(this IRegistrator registrator, string key)
where TFrom : class
where TTO : class, TFrom
{
RegisterTransient(registrator, typeof(TFrom), typeof(TTO), key);
return registrator;
}
/// <summary>
/// 注册临时映射
/// </summary>
/// <param name="registrator"></param>
/// <param name="fromType"></param>
/// <returns></returns>
public static IRegistrator RegisterTransient(this IRegistrator registrator, Type fromType)
{
RegisterTransient(registrator, fromType, fromType);
return registrator;
}
/// <summary>
/// 注册临时映射
/// </summary>
/// <param name="registrator"></param>
/// <param name="fromType"></param>
/// <param name="key"></param>
/// <returns></returns>
public static IRegistrator RegisterTransient(this IRegistrator registrator, Type fromType, string key)
{
RegisterTransient(registrator, fromType, fromType, key);
return registrator;
}
/// <summary>
/// 注册临时映射
/// </summary>
/// <param name="registrator"></param>
/// <param name="fromType"></param>
/// <param name="toType"></param>
/// <returns></returns>
public static IRegistrator RegisterTransient(this IRegistrator registrator, Type fromType, Type toType)
{
registrator.Register(new DependencyDescriptor(fromType, toType, Lifetime.Transient));
return registrator;
}
/// <summary>
/// 注册临时映射
/// </summary>
/// <param name="registrator"></param>
/// <param name="fromType"></param>
/// <param name="toType"></param>
/// <param name="key"></param>
/// <returns></returns>
public static IRegistrator RegisterTransient(this IRegistrator registrator, Type fromType, Type toType, string key)
{
registrator.Register(new DependencyDescriptor(fromType, toType, Lifetime.Transient), key);
return registrator;
}
/// <summary>
/// 注册临时映射
/// </summary>
/// <param name="registrator"></param>
/// <param name="func"></param>
/// <returns></returns>
public static IRegistrator RegisterTransient<TFrom>(this IRegistrator registrator, Func<IResolver, object> func)
{
registrator.Register(new DependencyDescriptor(typeof(TFrom), Lifetime.Transient)
{
ImplementationFactory = func
});
return registrator;
}
/// <summary>
/// 注册临时映射
/// </summary>
/// <param name="registrator"></param>
/// <param name="func"></param>
/// <param name="key"></param>
/// <returns></returns>
public static IRegistrator RegisterTransient<TFrom>(this IRegistrator registrator, Func<IResolver, object> func, string key)
{
registrator.Register(new DependencyDescriptor(typeof(TFrom), Lifetime.Transient)
{
ImplementationFactory = func
}, key);
return registrator;
}
/// <summary>
/// 注册临时映射
/// </summary>
/// <param name="registrator"></param>
/// <param name="fromType"></param>
/// <param name="func"></param>
/// <returns></returns>
public static IRegistrator RegisterTransient(this IRegistrator registrator, Type fromType, Func<IResolver, object> func)
{
registrator.Register(new DependencyDescriptor(fromType, Lifetime.Transient)
{
ImplementationFactory = func
});
return registrator;
}
/// <summary>
/// 注册临时映射
/// </summary>
/// <param name="registrator"></param>
/// <param name="fromType"></param>
/// <param name="func"></param>
/// <param name="key"></param>
/// <returns></returns>
public static IRegistrator RegisterTransient(this IRegistrator registrator, Type fromType, Func<IResolver, object> func, string key)
{
registrator.Register(new DependencyDescriptor(fromType, Lifetime.Transient)
{
ImplementationFactory = func
}, key);
return registrator;
}
#endregion Transient
#region Unregister
/// <summary>
/// 移除注册信息
/// </summary>
/// <param name="registrator"></param>
/// <param name="fromType"></param>
/// <returns></returns>
public static IRegistrator Unregister(this IRegistrator registrator, Type fromType)
{
registrator.Unregister(new DependencyDescriptor(fromType));
return registrator;
}
/// <summary>
/// 移除注册信息
/// </summary>
/// <param name="registrator"></param>
/// <param name="fromType"></param>
/// <param name="key"></param>
/// <returns></returns>
public static IRegistrator Unregister(this IRegistrator registrator, Type fromType, string key)
{
registrator.Unregister(new DependencyDescriptor(fromType), key);
return registrator;
}
/// <summary>
/// 移除注册信息
/// </summary>
/// <param name="registrator"></param>
/// <returns></returns>
public static IRegistrator Unregister<TFrom>(this IRegistrator registrator)
{
registrator.Unregister(new DependencyDescriptor(typeof(TFrom)));
return registrator;
}
/// <summary>
/// 移除注册信息
/// </summary>
/// <param name="registrator"></param>
/// <param name="key"></param>
/// <returns></returns>
public static IRegistrator Unregister<TFrom>(this IRegistrator registrator, string key)
{
registrator.Unregister(new DependencyDescriptor(typeof(TFrom)), key);
return registrator;
}
#endregion Unregister
#region Resolve
/// <summary>
/// 创建类型对应的实例
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="resolver"></param>
/// <returns></returns>
public static T Resolve<T>(this IResolver resolver)
{
return (T)resolver.Resolve(typeof(T));
}
/// <summary>
/// 创建类型对应的实例
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="resolver"></param>
/// <param name="key"></param>
/// <returns></returns>
public static T Resolve<T>(this IResolver resolver, string key)
{
return (T)resolver.Resolve(typeof(T), key);
}
/// <summary>
/// 创建<see cref="Lifetime.Transient"/>生命的未注册的根类型实例。一般适用于:目标类型没有注册,但是其成员类型已经注册的情况。
/// </summary>
/// <param name="resolver"></param>
/// <param name="fromType"></param>
/// <returns></returns>
/// <exception cref="Exception"></exception>
public static object ResolveWithoutRoot(this IResolver resolver, Type fromType)
{
object[] ops = null;
var ctor = fromType.GetConstructors().FirstOrDefault(x => x.IsDefined(typeof(DependencyInjectAttribute), true));
if (ctor is null)
{
//如果没有被特性标记,那就取构造函数参数最多的作为注入目标
if (fromType.GetConstructors().Length == 0)
{
throw new Exception($"没有找到类型{fromType.FullName}的公共构造函数。");
}
ctor = fromType.GetConstructors().OrderByDescending(x => x.GetParameters().Length).First();
}
DependencyTypeAttribute dependencyTypeAttribute = null;
if (fromType.IsDefined(typeof(DependencyTypeAttribute), true))
{
dependencyTypeAttribute = fromType.GetCustomAttribute<DependencyTypeAttribute>();
}
var parameters = ctor.GetParameters();
var ps = new object[parameters.Length];
if (dependencyTypeAttribute == null || dependencyTypeAttribute.Type.HasFlag(DependencyType.Constructor))
{
for (var i = 0; i < parameters.Length; i++)
{
if (ops != null && ops.Length - 1 >= i)
{
ps[i] = ops[i];
}
else
{
if (parameters[i].ParameterType.IsPrimitive || parameters[i].ParameterType == typeof(string))
{
ps[i] = parameters[i].HasDefaultValue ? parameters[i].DefaultValue : default;
}
else
{
if (parameters[i].IsDefined(typeof(DependencyInjectAttribute), true))
{
var attribute = parameters[i].GetCustomAttribute<DependencyInjectAttribute>();
var type = attribute.Type ?? parameters[i].ParameterType;
ps[i] = resolver.Resolve(type, attribute.Key);
}
else
{
ps[i] = resolver.Resolve(parameters[i].ParameterType);
}
}
}
}
}
if (ps == null || ps.Length == 0)
{
return Activator.CreateInstance(fromType);
}
return Activator.CreateInstance(fromType, ps);
}
/// <summary>
/// 创建<see cref="Lifetime.Transient"/>生命的未注册的根类型实例。一般适用于:目标类型没有注册,但是其成员类型已经注册的情况。
/// </summary>
/// <param name="resolver"></param>
/// <returns></returns>
/// <exception cref="Exception"></exception>
public static T ResolveWithoutRoot<T>(this IResolver resolver)
{
return (T)ResolveWithoutRoot(resolver, typeof(T));
}
/// <summary>
/// 尝试创建类型对应的实例如果类型没有注册则会返回null或者默认值类型。
/// </summary>
/// <param name="resolver"></param>
/// <param name="fromType"></param>
/// <returns></returns>
public static object TryResolve(this IResolver resolver, Type fromType)
{
if (resolver.IsRegistered(fromType))
{
return resolver.Resolve(fromType);
}
return default;
}
/// <summary>
/// 尝试创建类型对应的实例如果类型没有注册则会返回null或者默认值类型。
/// </summary>
/// <param name="resolver"></param>
/// <param name="fromType"></param>
/// <param name="key"></param>
/// <returns></returns>
public static object TryResolve(this IResolver resolver, Type fromType, string key)
{
if (resolver.IsRegistered(fromType))
{
return resolver.Resolve(fromType, key);
}
return default;
}
/// <summary>
/// 尝试创建类型对应的实例如果类型没有注册则会返回null或者默认值类型。
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="resolver"></param>
/// <returns></returns>
public static T TryResolve<T>(this IResolver resolver)
{
return (T)TryResolve(resolver, typeof(T));
}
/// <summary>
/// 尝试创建类型对应的实例如果类型没有注册则会返回null或者默认值类型。
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="resolver"></param>
/// <param name="key"></param>
/// <returns></returns>
public static T TryResolve<T>(this IResolver resolver, string key)
{
return (T)TryResolve(resolver, typeof(T), key);
}
#endregion Resolve
#region IsRegistered
/// <summary>
/// <inheritdoc cref="IRegistered.IsRegistered(Type)"/>
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="registered"></param>
/// <returns></returns>
public static bool IsRegistered<T>(this IRegistered registered)
{
return registered.IsRegistered(typeof(T));
}
/// <summary>
/// <inheritdoc cref="IRegistered.IsRegistered(Type, string)"/>
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="registered"></param>
/// <param name="key"></param>
/// <returns></returns>
public static bool IsRegistered<T>(this IRegistered registered, string key)
{
return registered.IsRegistered(typeof(T), key);
}
#endregion
}
}

View File

@@ -1,14 +1,14 @@
#region copyright
//------------------------------------------------------------------------------
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
// 代码版权除特别声明外的代码归作者本人Diego所有
// 源代码使用协议遵循本仓库的开源协议及附加协议
// Gitee源代码仓库https://gitee.com/diego2098/ThingsGateway
// Github源代码仓库https://github.com/kimdiego2098/ThingsGateway
// 使用文档https://diego2098.gitee.io/thingsgateway-docs/
// QQ群605534569
// 此代码版权除特别声明或在XREF结尾的命名空间的代码归作者本人若汝棋茗所有
// 代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// API首页http://rrqm_home.gitee.io/touchsocket/
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
#endregion
namespace ThingsGateway.Foundation.Core
{
@@ -34,4 +34,4 @@ namespace ThingsGateway.Foundation.Core
/// </summary>
Method = 2
}
}
}

View File

@@ -0,0 +1,22 @@
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在XREF结尾的命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// API首页http://rrqm_home.gitee.io/touchsocket/
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
namespace ThingsGateway.Foundation.Core
{
/// <summary>
/// 注入容器接口
/// </summary>
public interface IContainer : IResolver, IRegistrator
{
}
}

View File

@@ -0,0 +1,36 @@
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在XREF结尾的命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// API首页http://rrqm_home.gitee.io/touchsocket/
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
namespace ThingsGateway.Foundation.Core
{
/// <summary>
/// IRegistered
/// </summary>
public interface IRegistered
{
/// <summary>
/// 判断某类型是否已经注册
/// </summary>
/// <param name="fromType"></param>
/// <param name="key"></param>
/// <returns></returns>
bool IsRegistered(Type fromType, string key);
/// <summary>
/// 判断某类型是否已经注册
/// </summary>
/// <param name="fromType"></param>
/// <returns></returns>
bool IsRegistered(Type fromType);
}
}

View File

@@ -1,15 +1,3 @@
#region copyright
//------------------------------------------------------------------------------
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
// 此代码版权除特别声明外的代码归作者本人Diego所有
// 源代码使用协议遵循本仓库的开源协议及附加协议
// Gitee源代码仓库https://gitee.com/diego2098/ThingsGateway
// Github源代码仓库https://github.com/kimdiego2098/ThingsGateway
// 使用文档https://diego2098.gitee.io/thingsgateway-docs/
// QQ群605534569
//------------------------------------------------------------------------------
#endregion
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在XREF结尾的命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
@@ -21,37 +9,27 @@
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
namespace ThingsGateway.Foundation.Core
{
/// <summary>
/// 注入容器接口
/// 容器注册器
/// </summary>
public interface IContainer : IEnumerable<DependencyDescriptor>
public interface IRegistrator : IRegistered
{
/// <summary>
/// 创建目标类型的对应实例。
/// </summary>
/// <param name="fromType"></param>
/// <param name="key"></param>
/// <returns></returns>
object Resolve(Type fromType, string key = "");
/// <summary>
/// 判断某类型是否已经注册
/// </summary>
/// <param name="fromType"></param>
/// <param name="key"></param>
/// <returns></returns>
bool IsRegistered(Type fromType, string key = "");
/// <summary>
/// 添加类型描述符。
/// </summary>
/// <param name="key"></param>
/// <param name="descriptor"></param>
void Register(DependencyDescriptor descriptor, string key = "");
void Register(DependencyDescriptor descriptor, string key);
/// <summary>
/// 添加类型描述符
/// </summary>
/// <param name="descriptor"></param>
void Register(DependencyDescriptor descriptor);
/// <summary>
/// 移除注册信息。
@@ -59,6 +37,24 @@ namespace ThingsGateway.Foundation.Core
/// <param name="descriptor"></param>
/// <param name="key"></param>
/// <returns></returns>
void Unregister(DependencyDescriptor descriptor, string key = "");
void Unregister(DependencyDescriptor descriptor, string key);
/// <summary>
/// 移除注册信息
/// </summary>
/// <param name="descriptor"></param>
void Unregister(DependencyDescriptor descriptor);
/// <summary>
/// 获取已注册的所有类型描述
/// </summary>
/// <returns></returns>
IEnumerable<DependencyDescriptor> GetDescriptors();
/// <summary>
/// 构建一个服务获取器
/// </summary>
/// <returns></returns>
IResolver BuildResolver();
}
}

View File

@@ -0,0 +1,35 @@
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在XREF结尾的命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// API首页http://rrqm_home.gitee.io/touchsocket/
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
namespace ThingsGateway.Foundation.Core
{
/// <summary>
/// IResolver
/// </summary>
public interface IResolver : IServiceProvider, IRegistered
{
/// <summary>
/// 创建目标类型的对应实例。
/// </summary>
/// <param name="fromType"></param>
/// <param name="key"></param>
/// <returns></returns>
object Resolve(Type fromType, string key);
/// <summary>
/// 创建目标类型的对应实例。
/// </summary>
/// <param name="fromType"></param>
/// <returns></returns>
object Resolve(Type fromType);
}
}

View File

@@ -0,0 +1,25 @@
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在XREF结尾的命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// API首页http://rrqm_home.gitee.io/touchsocket/
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
namespace ThingsGateway.Foundation.Core
{
/// <summary>
/// IResolverObject
/// </summary>
public interface IResolverObject
{
/// <summary>
/// Resolver
/// </summary>
IResolver Resolver { get; }
}
}

View File

@@ -0,0 +1,30 @@
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在XREF结尾的命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// API首页http://rrqm_home.gitee.io/touchsocket/
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
namespace ThingsGateway.Foundation.Core
{
/// <summary>
/// 注入项的生命周期。
/// </summary>
public enum Lifetime
{
/// <summary>
/// 单例对象
/// </summary>
Singleton,
/// <summary>
/// 瞬时对象
/// </summary>
Transient
}
}

View File

@@ -0,0 +1,192 @@
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在XREF结尾的命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// API首页http://rrqm_home.gitee.io/touchsocket/
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
using System.Collections.Concurrent;
namespace ThingsGateway.Foundation.Core
{
/// <summary>
/// 手动IOC容器
/// </summary>
public abstract class ManualContainer : IContainer
{
private readonly ConcurrentDictionary<string, object> m_singletonInstances = new ConcurrentDictionary<string, object>();
/// <inheritdoc/>
public IResolver BuildResolver()
{
return this;
}
/// <inheritdoc/>
public IEnumerable<DependencyDescriptor> GetDescriptors()
{
throw new NotImplementedException();
}
/// <inheritdoc/>
public object GetService(Type serviceType)
{
return this.Resolve(serviceType);
}
/// <summary>
/// 判断指定的类型是否已在容器中注册。
/// <para>
/// 在本容器中,一般均会返回<see langword="true"/>。
/// </para>
/// </summary>
/// <param name="fromType"></param>
/// <param name="key"></param>
/// <returns></returns>
public virtual bool IsRegistered(Type fromType, string key)
{
return true;
}
/// <summary>
/// 判断指定的类型是否已在容器中注册。
/// <para>
/// 在本容器中,一般均会返回<see langword="true"/>。
/// </para>
/// </summary>
/// <param name="fromType"></param>
/// <returns></returns>
public virtual bool IsRegistered(Type fromType)
{
return true;
}
/// <summary>
/// 注册描述符。
/// <para>
/// 一般情况下,本容器只会处理单例实例模式。
/// </para>
/// </summary>
/// <param name="descriptor"></param>
/// <param name="key"></param>
public virtual void Register(DependencyDescriptor descriptor, string key)
{
if (descriptor.Lifetime == Lifetime.Singleton)
{
if (descriptor.ToInstance != null)
{
this.m_singletonInstances.AddOrUpdate($"{descriptor.FromType.FullName}{key}", descriptor.ToInstance, (k, v) => descriptor.ToInstance);
}
}
}
/// <summary>
/// 注册描述符。
/// <para>
/// 一般情况下,本容器只会处理单例实例模式。
/// </para>
/// </summary>
/// <param name="descriptor"></param>
public virtual void Register(DependencyDescriptor descriptor)
{
if (descriptor.Lifetime == Lifetime.Singleton)
{
if (descriptor.ToInstance != null)
{
this.m_singletonInstances.AddOrUpdate(descriptor.FromType.FullName, descriptor.ToInstance, (k, v) => descriptor.ToInstance);
}
}
}
/// <inheritdoc/>
/// <exception cref="Exception"></exception>
public object Resolve(Type fromType, string key)
{
if (fromType == typeof(IResolver) || fromType == typeof(IServiceProvider))
{
return this;
}
if (this.TryResolve(fromType, out var instance, key))
{
return instance;
}
throw new Exception($"没有解决容器所需类型:{fromType.FullName}");
}
/// <inheritdoc/>
/// <exception cref="Exception"></exception>
public object Resolve(Type fromType)
{
if (fromType == typeof(IResolver) || fromType == typeof(IServiceProvider))
{
return this;
}
if (this.TryResolve(fromType, out var instance))
{
return instance;
}
throw new Exception($"没有解决容器所需类型:{fromType.FullName}");
}
/// <summary>
/// 默认不实现该功能
/// </summary>
/// <param name="descriptor"></param>
/// <param name="key"></param>
/// <exception cref="NotImplementedException"></exception>
public virtual void Unregister(DependencyDescriptor descriptor, string key)
{
throw new NotImplementedException();
}
/// <summary>
/// 默认不实现该功能
/// </summary>
/// <param name="descriptor"></param>
/// <exception cref="NotImplementedException"></exception>
public virtual void Unregister(DependencyDescriptor descriptor)
{
throw new NotImplementedException();
}
/// <summary>
/// 尝试解决Ioc容器所需类型。
/// <para>
/// 本方法仅实现了在单例实例注册下的获取。
/// </para>
/// </summary>
/// <param name="fromType"></param>
/// <param name="instance"></param>
/// <param name="key"></param>
/// <returns></returns>
protected virtual bool TryResolve(Type fromType, out object instance, string key)
{
if (key.IsNullOrEmpty())
{
return this.m_singletonInstances.TryGetValue(fromType.FullName, out instance);
}
return this.m_singletonInstances.TryGetValue($"{fromType.FullName}{key}", out instance);
}
/// <summary>
/// 尝试解决Ioc容器所需类型。
/// <para>
/// 本方法仅实现了在单例实例注册下的获取。
/// </para>
/// </summary>
/// <param name="fromType"></param>
/// <param name="instance"></param>
/// <returns></returns>
protected virtual bool TryResolve(Type fromType, out object instance)
{
return this.m_singletonInstances.TryGetValue(fromType.FullName, out instance);
}
}
}

View File

@@ -86,5 +86,19 @@ namespace ThingsGateway.Foundation.Core
}
#endregion
/// <summary>
/// 将对象构建到字节数组
/// </summary>
/// <param name="requestInfo"></param>
/// <returns></returns>
public static byte[] BuildAsBytes(this IRequestInfoBuilder requestInfo)
{
using (var byteBlock = new ByteBlock(requestInfo.MaxLength))
{
requestInfo.Build(byteBlock);
return byteBlock.ToArray();
}
}
}
}

View File

@@ -0,0 +1,36 @@
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在XREF结尾的命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// API首页http://rrqm_home.gitee.io/touchsocket/
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
namespace ThingsGateway.Foundation.Core
{
/// <summary>
/// 能对适配器做配置的客户端
/// </summary>
public interface IAdapterObject
{
/// <summary>
/// 是否允许自由调用<see cref="SetDataHandlingAdapter"/>进行赋值。
/// </summary>
bool CanSetDataHandlingAdapter { get; }
/// <summary>
/// 数据处理适配器
/// </summary>
SingleStreamDataHandlingAdapter DataHandlingAdapter { get; }
/// <summary>
/// 设置数据处理适配器
/// </summary>
/// <param name="adapter"></param>
void SetDataHandlingAdapter(SingleStreamDataHandlingAdapter adapter);
}
}

View File

@@ -26,18 +26,19 @@
namespace ThingsGateway.Foundation.Core
{
/// <summary>
/// 注入项的生命周期。
/// 指示<see cref="IRequestInfo"/>应当如何构建
/// </summary>
public enum Lifetime
public interface IRequestInfoBuilder
{
/// <summary>
/// 单例对象
/// 构建数据时,指示内存池的申请长度。
/// </summary>
Singleton,
int MaxLength { get; }
/// <summary>
/// 瞬时对象
/// 构建对象到<see cref="ByteBlock"/>
/// </summary>
Transient
/// <param name="byteBlock"></param>
void Build(ByteBlock byteBlock);
}
}
}

View File

@@ -39,22 +39,26 @@ namespace ThingsGateway.Foundation.Core
/// 是否启用缓存超时。默认false。
/// </summary>
public bool CacheTimeoutEnable { get; set; } = false;
/// <inheritdoc/>
public override bool CanSendRequestInfo => false;
/// <inheritdoc/>
public override bool CanSplicingSend => false;
/// <summary>
/// 当接收数据处理完成后,回调该函数执行接收
/// </summary>
public Action<ByteBlock, IRequestInfo> ReceivedCallBack { get; set; }
/// <summary>
/// 当发送数据处理完成后,回调该函数执行发送
/// </summary>
public Action<byte[], int, int> SendCallBack { get; set; }
/// <summary>
/// 当发送数据处理完成后,回调该函数执行异步发送
/// </summary>
public Func<byte[], int, int, Task> SendAsyncCallBack { get; set; }
/// <summary>
/// 当发送数据处理完成后,回调该函数执行发送
/// </summary>
public Action<byte[], int, int> SendCallBack { get; set; }
/// <summary>
/// 是否在收到数据时即刷新缓存时间。默认true。
/// <list type="number">
@@ -69,12 +73,6 @@ namespace ThingsGateway.Foundation.Core
/// </summary>
protected DateTime LastCacheTime { get; set; }
/// <inheritdoc/>
public override bool CanSendRequestInfo => false;
/// <inheritdoc/>
public override bool CanSplicingSend => false;
/// <summary>
/// 收到数据的切入点,该方法由框架自动调用。
/// </summary>
@@ -158,7 +156,16 @@ namespace ThingsGateway.Foundation.Core
/// <param name="requestInfo"></param>
protected virtual void PreviewSend(IRequestInfo requestInfo)
{
throw new NotImplementedException();
if (requestInfo == null)
{
throw new ArgumentNullException(nameof(requestInfo));
}
var requestInfoBuilder = (IRequestInfoBuilder)requestInfo;
using (var byteBlock = new ByteBlock(requestInfoBuilder.MaxLength))
{
requestInfoBuilder.Build(byteBlock);
this.GoSend(byteBlock.Buffer, 0, byteBlock.Len);
}
}
/// <summary>
@@ -186,9 +193,18 @@ namespace ThingsGateway.Foundation.Core
/// 当发送数据前预先处理数据
/// </summary>
/// <param name="requestInfo"></param>
protected virtual Task PreviewSendAsync(IRequestInfo requestInfo)
protected virtual async Task PreviewSendAsync(IRequestInfo requestInfo)
{
throw new NotImplementedException();
if (requestInfo == null)
{
throw new ArgumentNullException(nameof(requestInfo));
}
var requestInfoBuilder = (IRequestInfoBuilder)requestInfo;
using (var byteBlock = new ByteBlock(requestInfoBuilder.MaxLength))
{
requestInfoBuilder.Build(byteBlock);
await this.GoSendAsync(byteBlock.Buffer, 0, byteBlock.Len);
}
}
/// <summary>

View File

@@ -1,498 +0,0 @@
#region copyright
//------------------------------------------------------------------------------
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
// 此代码版权除特别声明外的代码归作者本人Diego所有
// 源代码使用协议遵循本仓库的开源协议及附加协议
// Gitee源代码仓库https://gitee.com/diego2098/ThingsGateway
// Github源代码仓库https://github.com/kimdiego2098/ThingsGateway
// 使用文档https://diego2098.gitee.io/thingsgateway-docs/
// QQ群605534569
//------------------------------------------------------------------------------
#endregion
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在XREF结尾的命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// API首页http://rrqm_home.gitee.io/touchsocket/
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
using System.Data;
using System.Reflection;
namespace ThingsGateway.Foundation.Core
{
/// <summary>
/// IContainerExtensions
/// </summary>
public static class ContainerExtension
{
#region RegisterSingleton
/// <summary>
/// 注册单例
/// </summary>
/// <typeparam name="TFrom"></typeparam>
/// <typeparam name="TTo"></typeparam>
/// <param name="container"></param>
/// <param name="instance"></param>
/// <returns></returns>
public static IContainer RegisterSingleton<TFrom, TTo>(this IContainer container, TTo instance)
where TFrom : class
where TTo : class, TFrom
{
RegisterSingleton(container, typeof(TFrom), instance);
return container;
}
/// <summary>
/// 注册单例
/// </summary>
/// <param name="container"></param>
/// <param name="instance"></param>
/// <returns></returns>
public static IContainer RegisterSingleton(this IContainer container, object instance)
{
if (instance is null)
{
throw new ArgumentNullException(nameof(instance));
}
RegisterSingleton(container, instance.GetType(), instance);
return container;
}
/// <summary>
/// 注册单例
/// </summary>
/// <param name="container"></param>
/// <param name="fromType"></param>
/// <returns></returns>
/// <exception cref="ArgumentNullException"></exception>
public static IContainer RegisterSingleton(this IContainer container, Type fromType)
{
if (fromType is null)
{
throw new ArgumentNullException(nameof(fromType));
}
RegisterSingleton(container, fromType, fromType);
return container;
}
/// <summary>
/// 注册单例
/// </summary>
/// <typeparam name="TFrom"></typeparam>
/// <typeparam name="TTo"></typeparam>
/// <param name="container"></param>
/// <param name="key"></param>
/// <param name="instance"></param>
/// <returns></returns>
public static IContainer RegisterSingleton<TFrom, TTo>(this IContainer container, string key, TTo instance)
where TFrom : class
where TTo : class, TFrom
{
RegisterSingleton(container, typeof(TFrom), instance, key);
return container;
}
/// <summary>
/// 注册单例
/// </summary>
/// <param name="container"></param>
/// <param name="fromType"></param>
/// <param name="instance"></param>
/// <param name="key"></param>
/// <returns></returns>
public static IContainer RegisterSingleton(this IContainer container, Type fromType, object instance, string key = "")
{
container.Register(new DependencyDescriptor(fromType, instance), key);
return container;
}
/// <summary>
/// 注册单例
/// </summary>
/// <typeparam name="TFrom"></typeparam>
/// <param name="container"></param>
/// <param name="instance"></param>
/// <param name="key"></param>
/// <returns></returns>
public static IContainer RegisterSingleton<TFrom>(this IContainer container, object instance, string key = "")
{
container.Register(new DependencyDescriptor(typeof(TFrom), instance), key);
return container;
}
/// <summary>
/// 注册单例
/// </summary>
/// <param name="container"></param>
/// <param name="instance"></param>
/// <param name="key"></param>
/// <returns></returns>
public static IContainer RegisterSingleton(this IContainer container, object instance, string key = "")
{
container.Register(new DependencyDescriptor(instance.GetType(), instance), key);
return container;
}
/// <summary>
/// 注册单例
/// </summary>
/// <typeparam name="TFrom"></typeparam>
/// <param name="container"></param>
/// <param name="key"></param>
/// <returns></returns>
public static IContainer RegisterSingleton<TFrom>(this IContainer container, string key = "")
{
container.Register(new DependencyDescriptor(typeof(TFrom), typeof(TFrom), Lifetime.Singleton), key);
return container;
}
/// <summary>
/// 注册单例
/// </summary>
/// <param name="container"></param>
/// <param name="fromType"></param>
/// <param name="toType"></param>
/// <param name="key"></param>
/// <returns></returns>
public static IContainer RegisterSingleton(this IContainer container, Type fromType, Type toType, string key = "")
{
container.Register(new DependencyDescriptor(fromType, toType, Lifetime.Singleton), key);
return container;
}
/// <summary>
/// 注册单例
/// </summary>
/// <param name="container"></param>
/// <param name="func"></param>
/// <param name="key"></param>
/// <returns></returns>
public static IContainer RegisterSingleton<TFrom>(this IContainer container, Func<IContainer, object> func, string key = "")
{
container.Register(new DependencyDescriptor(typeof(TFrom), Lifetime.Singleton)
{
ImplementationFactory = func
}, key);
return container;
}
/// <summary>
/// 注册单例
/// </summary>
/// <param name="container"></param>
/// <param name="fromType"></param>
/// <param name="func"></param>
/// <param name="key"></param>
/// <returns></returns>
public static IContainer RegisterSingleton(this IContainer container, Type fromType, Func<IContainer, object> func, string key = "")
{
container.Register(new DependencyDescriptor(fromType, Lifetime.Singleton)
{
ImplementationFactory = func
}, key);
return container;
}
/// <summary>
/// 注册单例
/// </summary>
/// <typeparam name="TFrom"></typeparam>
/// <typeparam name="TTO"></typeparam>
/// <param name="container"></param>
/// <returns></returns>
public static IContainer RegisterSingleton<TFrom, TTO>(this IContainer container)
where TFrom : class
where TTO : class, TFrom
{
RegisterSingleton(container, typeof(TFrom), typeof(TTO));
return container;
}
/// <summary>
/// 注册单例
/// </summary>
/// <typeparam name="TFrom"></typeparam>
/// <typeparam name="TTO"></typeparam>
/// <param name="container"></param>
/// <param name="key"></param>
/// <returns></returns>
public static IContainer RegisterSingleton<TFrom, TTO>(this IContainer container, string key)
where TFrom : class
where TTO : class, TFrom
{
RegisterSingleton(container, typeof(TFrom), typeof(TTO), key);
return container;
}
#endregion RegisterSingleton
#region Transient
/// <summary>
/// 注册临时映射
/// </summary>
/// <typeparam name="TFrom"></typeparam>
/// <typeparam name="TTO"></typeparam>
/// <param name="container"></param>
/// <returns></returns>
public static IContainer RegisterTransient<TFrom, TTO>(this IContainer container)
where TFrom : class
where TTO : class, TFrom
{
RegisterTransient(container, typeof(TFrom), typeof(TTO));
return container;
}
/// <summary>
/// 注册临时映射
/// </summary>
/// <typeparam name="TFrom"></typeparam>
/// <param name="container"></param>
/// <param name="key"></param>
/// <returns></returns>
public static IContainer RegisterTransient<TFrom>(this IContainer container, string key = "")
where TFrom : class
{
RegisterTransient(container, typeof(TFrom), typeof(TFrom), key);
return container;
}
/// <summary>
/// 注册临时映射
/// </summary>
/// <typeparam name="TFrom"></typeparam>
/// <typeparam name="TTO"></typeparam>
/// <param name="container"></param>
/// <param name="key"></param>
/// <returns></returns>
public static IContainer RegisterTransient<TFrom, TTO>(this IContainer container, string key = "")
where TFrom : class
where TTO : class, TFrom
{
RegisterTransient(container, typeof(TFrom), typeof(TTO), key);
return container;
}
/// <summary>
/// 注册临时映射
/// </summary>
/// <param name="container"></param>
/// <param name="fromType"></param>
/// <param name="key"></param>
/// <returns></returns>
public static IContainer RegisterTransient(this IContainer container, Type fromType, string key = "")
{
RegisterTransient(container, fromType, fromType, key);
return container;
}
/// <summary>
/// 注册临时映射
/// </summary>
/// <param name="container"></param>
/// <param name="fromType"></param>
/// <param name="toType"></param>
/// <param name="key"></param>
/// <returns></returns>
public static IContainer RegisterTransient(this IContainer container, Type fromType, Type toType, string key = "")
{
container.Register(new DependencyDescriptor(fromType, toType, Lifetime.Transient), key);
return container;
}
/// <summary>
/// 注册临时映射
/// </summary>
/// <param name="container"></param>
/// <param name="func"></param>
/// <param name="key"></param>
/// <returns></returns>
public static IContainer RegisterTransient<TFrom>(this IContainer container, Func<IContainer, object> func, string key = "")
{
container.Register(new DependencyDescriptor(typeof(TFrom), Lifetime.Transient)
{
ImplementationFactory = func
}, key);
return container;
}
/// <summary>
/// 注册临时映射
/// </summary>
/// <param name="container"></param>
/// <param name="fromType"></param>
/// <param name="func"></param>
/// <param name="key"></param>
/// <returns></returns>
public static IContainer RegisterTransient(this IContainer container, Type fromType, Func<IContainer, object> func, string key = "")
{
container.Register(new DependencyDescriptor(fromType, Lifetime.Transient)
{
ImplementationFactory = func
}, key);
return container;
}
#endregion Transient
#region Unregister
/// <summary>
/// 移除注册信息
/// </summary>
/// <param name="container"></param>
/// <param name="fromType"></param>
/// <param name="key"></param>
/// <returns></returns>
public static IContainer Unregister(this IContainer container, Type fromType, string key = "")
{
container.Unregister(new DependencyDescriptor(fromType), key);
return container;
}
/// <summary>
/// 移除注册信息
/// </summary>
/// <param name="container"></param>
/// <param name="key"></param>
/// <returns></returns>
public static IContainer Unregister<TFrom>(this IContainer container, string key = "")
{
container.Unregister(new DependencyDescriptor(typeof(TFrom)), key);
return container;
}
#endregion Unregister
#region Resolve
/// <summary>
/// 创建类型对应的实例
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="container"></param>
/// <param name="key"></param>
/// <returns></returns>
public static T Resolve<T>(this IContainer container, string key = "")
{
return (T)container.Resolve(typeof(T), key);
}
/// <summary>
/// 创建<see cref="Lifetime.Transient"/>生命的未注册的根类型实例。一般适用于:目标类型没有注册,但是其成员类型已经注册的情况。
/// </summary>
/// <param name="container"></param>
/// <param name="fromType"></param>
/// <returns></returns>
/// <exception cref="Exception"></exception>
public static object ResolveWithoutRoot(this IContainer container, Type fromType)
{
object[] ops = null;
var ctor = fromType.GetConstructors().FirstOrDefault(x => x.IsDefined(typeof(DependencyInjectAttribute), true));
if (ctor is null)
{
//如果没有被特性标记,那就取构造函数参数最多的作为注入目标
if (fromType.GetConstructors().Length == 0)
{
throw new Exception($"没有找到类型{fromType.FullName}的公共构造函数。");
}
ctor = fromType.GetConstructors().OrderByDescending(x => x.GetParameters().Length).First();
}
DependencyTypeAttribute dependencyTypeAttribute = null;
if (fromType.IsDefined(typeof(DependencyTypeAttribute), true))
{
dependencyTypeAttribute = fromType.GetCustomAttribute<DependencyTypeAttribute>();
}
var parameters = ctor.GetParameters();
var ps = new object[parameters.Length];
if (dependencyTypeAttribute == null || dependencyTypeAttribute.Type.HasFlag(DependencyType.Constructor))
{
for (var i = 0; i < parameters.Length; i++)
{
if (ops != null && ops.Length - 1 >= i)
{
ps[i] = ops[i];
}
else
{
if (parameters[i].ParameterType.IsPrimitive || parameters[i].ParameterType == typeof(string))
{
ps[i] = parameters[i].HasDefaultValue ? parameters[i].DefaultValue : default;
}
else
{
if (parameters[i].IsDefined(typeof(DependencyInjectAttribute), true))
{
var attribute = parameters[i].GetCustomAttribute<DependencyInjectAttribute>();
var type = attribute.Type ?? parameters[i].ParameterType;
ps[i] = container.Resolve(type, attribute.Key);
}
else
{
ps[i] = container.Resolve(parameters[i].ParameterType, null);
}
}
}
}
}
if (ps == null || ps.Length == 0)
{
return Activator.CreateInstance(fromType);
}
return Activator.CreateInstance(fromType, ps);
}
/// <summary>
/// 创建<see cref="Lifetime.Transient"/>生命的未注册的根类型实例。一般适用于:目标类型没有注册,但是其成员类型已经注册的情况。
/// </summary>
/// <param name="container"></param>
/// <returns></returns>
/// <exception cref="Exception"></exception>
public static T ResolveWithoutRoot<T>(this IContainer container)
{
return (T)ResolveWithoutRoot(container, typeof(T));
}
/// <summary>
/// 尝试创建类型对应的实例如果类型没有注册则会返回null或者默认值类型。
/// </summary>
/// <param name="container"></param>
/// <param name="fromType"></param>
/// <param name="key"></param>
/// <returns></returns>
public static object TryResolve(this IContainer container, Type fromType, string key = "")
{
if (container.IsRegistered(fromType))
{
return container.Resolve(fromType, key);
}
return default;
}
/// <summary>
/// 尝试创建类型对应的实例如果类型没有注册则会返回null或者默认值类型。
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="container"></param>
/// <param name="key"></param>
/// <returns></returns>
public static T TryResolve<T>(this IContainer container, string key = "")
{
return (T)TryResolve(container, typeof(T), key);
}
#endregion Resolve
}
}

View File

@@ -42,13 +42,6 @@ namespace ThingsGateway.Foundation.Core
this.Lifetime = Lifetime.Singleton;
this.ToType = instance.GetType();
}
/// <summary>
/// 在获取到注册时触发委托。
/// <para>
/// 在单例实例注册时,不会触发。在单例注册时,只会触发一次,在瞬态注册时,会每次都触发。
/// </para>
/// </summary>
public Action<object> OnResolved { get; set; }
/// <summary>
/// 初始化一个完整的服务注册
@@ -72,20 +65,15 @@ namespace ThingsGateway.Foundation.Core
this.FromType = fromType;
}
/// <summary>
/// 注册类型
/// </summary>
public Type FromType { get; }
/// <summary>
/// 实例化工厂委托
/// </summary>
public Func<IContainer, object> ImplementationFactory { get; set; }
/// <summary>
/// 实例类型
/// </summary>
public Type ToType { get; }
/// <summary>
/// 实例
/// </summary>
public object ToInstance { get; set; }
public Func<IResolver, object> ImplementationFactory { get; set; }
/// <summary>
/// 生命周期
@@ -93,8 +81,21 @@ namespace ThingsGateway.Foundation.Core
public Lifetime Lifetime { get; }
/// <summary>
/// 注册类型
/// 在获取到注册时触发委托。
/// <para>
/// 在单例实例注册时,不会触发。在单例注册时,只会触发一次,在瞬态注册时,会每次都触发。
/// </para>
/// </summary>
public Type FromType { get; }
public Action<object> OnResolved { get; set; }
/// <summary>
/// 实例
/// </summary>
public object ToInstance { get; set; }
/// <summary>
/// 实例类型
/// </summary>
public Type ToType { get; }
}
}

View File

@@ -1,114 +0,0 @@
#region copyright
//------------------------------------------------------------------------------
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
// 此代码版权除特别声明外的代码归作者本人Diego所有
// 源代码使用协议遵循本仓库的开源协议及附加协议
// Gitee源代码仓库https://gitee.com/diego2098/ThingsGateway
// Github源代码仓库https://github.com/kimdiego2098/ThingsGateway
// 使用文档https://diego2098.gitee.io/thingsgateway-docs/
// QQ群605534569
//------------------------------------------------------------------------------
#endregion
using System.Collections;
using System.Collections.Concurrent;
namespace ThingsGateway.Foundation.Core
{
/// <summary>
/// 手动IOC容器
/// </summary>
public abstract class ManualContainer : IContainer
{
private readonly ConcurrentDictionary<string, object> m_singletonInstances = new ConcurrentDictionary<string, object>();
IEnumerator<DependencyDescriptor> IEnumerable<DependencyDescriptor>.GetEnumerator()
{
throw new NotImplementedException();
}
IEnumerator IEnumerable.GetEnumerator()
{
throw new NotImplementedException();
}
/// <summary>
/// 判断指定的类型是否已在容器中注册。
/// <para>
/// 在本容器中,一般均会返回<see langword="true"/>。
/// </para>
/// </summary>
/// <param name="fromType"></param>
/// <param name="key"></param>
/// <returns></returns>
public virtual bool IsRegistered(Type fromType, string key = "")
{
return true;
}
/// <summary>
/// 注册描述符。
/// <para>
/// 一般情况下,本容器只会处理单例实例模式。
/// </para>
/// </summary>
/// <param name="descriptor"></param>
/// <param name="key"></param>
public virtual void Register(DependencyDescriptor descriptor, string key = "")
{
if (descriptor.Lifetime == Lifetime.Singleton)
{
if (descriptor.ToInstance != null)
{
this.m_singletonInstances.AddOrUpdate($"{descriptor.FromType.FullName}{key}", descriptor.ToInstance, (k, v) => descriptor.ToInstance);
}
}
}
/// <inheritdoc/>
/// <exception cref="Exception"></exception>
public object Resolve(Type fromType, string key = "")
{
if (fromType.FullName == "ThingsGateway.Foundation.Core.IContainer")
{
return this;
}
if (this.TryResolve(fromType, out var instance, key))
{
return instance;
}
throw new Exception($"没有解决容器所需类型:{fromType.FullName}");
}
/// <summary>
/// 默认不实现该功能
/// </summary>
/// <param name="descriptor"></param>
/// <param name="key"></param>
/// <exception cref="NotImplementedException"></exception>
public virtual void Unregister(DependencyDescriptor descriptor, string key = "")
{
throw new NotImplementedException();
}
/// <summary>
/// 尝试解决Ioc容器所需类型。
/// <para>
/// 本方法仅实现了在单例实例注册下的获取。
/// </para>
/// </summary>
/// <param name="fromType"></param>
/// <param name="instance"></param>
/// <param name="key"></param>
/// <returns></returns>
protected virtual bool TryResolve(Type fromType, out object instance, string key = "")
{
if (key.IsNullOrEmpty())
{
return this.m_singletonInstances.TryGetValue(fromType.FullName, out instance);
}
return this.m_singletonInstances.TryGetValue($"{fromType.FullName}{key}", out instance);
}
}
}

View File

@@ -58,7 +58,8 @@ namespace ThingsGateway.Foundation.Core
else if (dt.Kind != DateTimeKind.Local)
return new DateTimeOffset(dt, offset).ToString("yyyy-MM-dd HH:mm:ss:fff zz");
}
return dt.ToString("yyyy-MM-dd HH:mm:ss:fff zz");
return new DateTimeOffset(dt, offset).ToString("yyyy-MM-dd HH:mm:ss:fff zz");
//return dt.ToString("yyyy-MM-dd HH:mm:ss:fff zz");
}
/// <summary>
/// 返回yyyy-MM-dd HH:mm:ss:fff zz时间格式字符串

View File

@@ -9,7 +9,6 @@
// QQ群605534569
//------------------------------------------------------------------------------
#endregion
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在XREF结尾的命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
@@ -21,7 +20,6 @@
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
namespace ThingsGateway.Foundation.Core
{
@@ -30,12 +28,59 @@ namespace ThingsGateway.Foundation.Core
/// </summary>
public static class LoggerContainerExtension
{
#region GroupLogger
/// <summary>
/// 添加控制台日志到日志组。
/// </summary>
/// <returns></returns>
public static void AddConsoleLogger(this LoggerGroup loggerGroup)
{
loggerGroup.AddLogger(ConsoleLogger.Default);
}
/// <summary>
/// 添加委托日志到日志组。
/// </summary>
/// <param name="loggerGroup"></param>
/// <param name="action"></param>
/// <returns></returns>
public static void AddEasyLogger(this LoggerGroup loggerGroup, Action<LogLevel, object, string, Exception> action)
{
loggerGroup.AddLogger(new EasyLogger(action));
}
/// <summary>
/// 添加委托日志到日志组。
/// </summary>
/// <param name="loggerGroup"></param>
/// <param name="action"></param>
/// <returns></returns>
public static void AddEasyLogger(this LoggerGroup loggerGroup, Action<string> action)
{
loggerGroup.AddLogger(new EasyLogger(action));
}
/// <summary>
/// 添加文件日志到日志组。
/// </summary>
/// <param name="loggerGroup"></param>
/// <param name="rootPath"></param>
/// <returns></returns>
public static void AddFileLogger(this LoggerGroup loggerGroup, string rootPath = "logs")
{
loggerGroup.AddLogger(new FileLogger(rootPath));
}
#endregion GroupLogger
#region Obsolete
/// <summary>
/// 添加控制台日志到日志组。
/// </summary>
/// <param name="container"></param>
/// <returns></returns>
public static IContainer AddConsoleLogger(this IContainer container)
public static IRegistrator AddConsoleLogger(this IRegistrator container)
{
AddLogger(container, ConsoleLogger.Default);
return container;
@@ -47,7 +92,7 @@ namespace ThingsGateway.Foundation.Core
/// <param name="container"></param>
/// <param name="action"></param>
/// <returns></returns>
public static IContainer AddEasyLogger(this IContainer container, Action<LogLevel, object, string, Exception> action)
public static IRegistrator AddEasyLogger(this IRegistrator container, Action<LogLevel, object, string, Exception> action)
{
AddLogger(container, new EasyLogger(action));
return container;
@@ -59,7 +104,7 @@ namespace ThingsGateway.Foundation.Core
/// <param name="container"></param>
/// <param name="action"></param>
/// <returns></returns>
public static IContainer AddEasyLogger(this IContainer container, Action<string> action)
public static IRegistrator AddEasyLogger(this IRegistrator container, Action<string> action)
{
AddLogger(container, new EasyLogger(action));
return container;
@@ -71,52 +116,62 @@ namespace ThingsGateway.Foundation.Core
/// <param name="container"></param>
/// <param name="rootPath"></param>
/// <returns></returns>
public static IContainer AddFileLogger(this IContainer container, string rootPath = "logs")
public static IRegistrator AddFileLogger(this IRegistrator container, string rootPath = "logs")
{
AddLogger(container, new FileLogger(rootPath));
return container;
}
#endregion
/// <summary>
/// 添加日志到日志组
/// 添加日志到容器
/// </summary>
/// <param name="container"></param>
/// <param name="registrator"></param>
/// <param name="logger"></param>
/// <returns></returns>
public static IContainer AddLogger(this IContainer container, ILog logger)
public static IRegistrator AddLogger(this IRegistrator registrator, ILog logger)
{
if (!container.IsRegistered(typeof(ILog)))
{
container.RegisterSingleton<ILog>(new LoggerGroup());
}
var loggerGroup = (LoggerGroup)container.Resolve<ILog>();
loggerGroup.AddLogger(logger);
return container;
registrator.RegisterSingleton<ILog>(logger);
return registrator;
}
/// <summary>
/// 添加日志组
/// </summary>
/// <param name="registrator"></param>
/// <param name="loggerAction"></param>
/// <returns></returns>
public static IRegistrator AddLogger(this IRegistrator registrator, Action<LoggerGroup> loggerAction)
{
var loggerGroup = new LoggerGroup();
loggerAction.Invoke(loggerGroup);
registrator.RegisterSingleton<ILog>(loggerGroup);
return registrator;
}
/// <summary>
/// 设置单例日志。
/// </summary>
/// <typeparam name="TLogger"></typeparam>
/// <param name="container"></param>
/// <param name="registrator"></param>
/// <returns></returns>
public static IContainer SetSingletonLogger<TLogger>(this IContainer container) where TLogger : class, ILog
public static IRegistrator SetSingletonLogger<TLogger>(this IRegistrator registrator) where TLogger : class, ILog
{
container.RegisterSingleton<ILog, TLogger>();
return container;
registrator.RegisterSingleton<ILog, TLogger>();
return registrator;
}
/// <summary>
/// 设置单例实例日志。
/// </summary>
/// <typeparam name="TLogger"></typeparam>
/// <param name="container"></param>
/// <param name="registrator"></param>
/// <param name="logger"></param>
/// <returns></returns>
public static IContainer SetSingletonLogger<TLogger>(this IContainer container, TLogger logger) where TLogger : class, ILog
public static IRegistrator SetSingletonLogger<TLogger>(this IRegistrator registrator, TLogger logger) where TLogger : class, ILog
{
container.RegisterSingleton<ILog, TLogger>(logger);
return container;
registrator.RegisterSingleton<ILog, TLogger>(logger);
return registrator;
}
}
}

View File

@@ -31,9 +31,9 @@ namespace ThingsGateway.Foundation.Core
public interface IPlugin : IDisposable
{
/// <summary>
/// 在插件被成功添加在<see cref="IPluginsManager"/>时执行。
/// 在插件被成功添加在<see cref="IPluginManager"/>时执行。
/// </summary>
/// <param name="pluginsManager"></param>
void Loaded(IPluginsManager pluginsManager);
/// <param name="pluginManager"></param>
void Loaded(IPluginManager pluginManager);
}
}

View File

@@ -23,12 +23,16 @@
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
#if NET6_0_OR_GREATER
using System.Diagnostics.CodeAnalysis;
#endif
namespace ThingsGateway.Foundation.Core
{
/// <summary>
/// 插件管理器接口
/// </summary>
public interface IPluginsManager : IDisposable
public interface IPluginManager : IDisposable
{
/// <summary>
/// 标识该插件管理器是否可用。
@@ -58,7 +62,11 @@ namespace ThingsGateway.Foundation.Core
/// 添加插件
/// </summary>
/// <param name="pluginType">插件类型</param>
#if NET6_0_OR_GREATER
object Add([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type pluginType);
#else
object Add(Type pluginType);
#endif
/// <summary>
/// 添加插件异步执行委托

View File

@@ -30,14 +30,9 @@ namespace ThingsGateway.Foundation.Core
/// </summary>
public interface IPluginObject
{
/// <summary>
/// IOC容器
/// </summary>
IContainer Container { get; }
/// <summary>
/// 插件管理器
/// </summary>
IPluginsManager PluginsManager { get; }
IPluginManager PluginManager { get; }
}
}

View File

@@ -18,14 +18,14 @@ namespace ThingsGateway.Foundation.Core
public class PluginBase : DisposableObject, IPlugin
{
/// <inheritdoc cref="IPlugin.Loaded(IPluginsManager)"/>
protected virtual void Loaded(IPluginsManager pluginsManager)
/// <inheritdoc cref="IPlugin.Loaded(IPluginManager)"/>
protected virtual void Loaded(IPluginManager pluginManager)
{
}
void IPlugin.Loaded(IPluginsManager pluginsManager)
void IPlugin.Loaded(IPluginManager pluginManager)
{
this.Loaded(pluginsManager);
this.Loaded(pluginManager);
}
}
}

View File

@@ -1,15 +1,3 @@
#region copyright
//------------------------------------------------------------------------------
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
// 此代码版权除特别声明外的代码归作者本人Diego所有
// 源代码使用协议遵循本仓库的开源协议及附加协议
// Gitee源代码仓库https://gitee.com/diego2098/ThingsGateway
// Github源代码仓库https://github.com/kimdiego2098/ThingsGateway
// 使用文档https://diego2098.gitee.io/thingsgateway-docs/
// QQ群605534569
//------------------------------------------------------------------------------
#endregion
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在XREF结尾的命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
@@ -21,7 +9,7 @@
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
using System.Reflection;
namespace ThingsGateway.Foundation.Core
@@ -29,20 +17,20 @@ namespace ThingsGateway.Foundation.Core
/// <summary>
/// 表示插件管理器。
/// </summary>
public class PluginsManager : DisposableObject, IPluginsManager
public class PluginManager : DisposableObject, IPluginManager
{
private readonly IContainer m_container;
private readonly object m_locker = new object();
private readonly Dictionary<string, PluginModel> m_pluginMethods = new Dictionary<string, PluginModel>();
private readonly List<IPlugin> m_plugins = new List<IPlugin>();
private readonly IResolver m_resolver;
/// <summary>
/// 表示插件管理器
/// </summary>
/// <param name="container"></param>
public PluginsManager(IContainer container)
/// <param name="resolver"></param>
public PluginManager(IResolver resolver)
{
this.m_container = container;
this.m_resolver = resolver;
}
/// <inheritdoc/>
@@ -51,7 +39,7 @@ namespace ThingsGateway.Foundation.Core
/// <inheritdoc/>
public IEnumerable<IPlugin> Plugins => this.m_plugins;
void IPluginsManager.Add(IPlugin plugin)
void IPluginManager.Add(IPlugin plugin)
{
if (plugin is null)
{
@@ -74,14 +62,6 @@ namespace ThingsGateway.Foundation.Core
}
}
}
if (!optionAttribute.NotRegister)
{
this.m_container.RegisterSingleton(plugin);
}
}
else
{
this.m_container.RegisterSingleton(plugin);
}
var list = this.SearchPluginMethod(plugin);
@@ -103,12 +83,6 @@ namespace ThingsGateway.Foundation.Core
var pluginModel = this.GetPluginModel(name);
var pluginEntity = new PluginEntity(new Method(methodInfo), plugin);
pluginModel.Funcs.Add(pluginEntity.Run);
//pluginModel.PluginEntities.Add(new PluginEntity(new Method(methodInfo), plugin));
//pluginModel.PluginEntities.Sort(delegate (PluginEntity x, PluginEntity y)
//{
// return x.Plugin.Order == y.Plugin.Order ? 0 : x.Plugin.Order < y.Plugin.Order ? 1 : -1;
//});
}
pairs.Add(name);
}
@@ -118,37 +92,7 @@ namespace ThingsGateway.Foundation.Core
}
}
private List<string> SearchPluginMethod(IPlugin plugin)
{
List<string> pluginMethodNames = new List<string>();
var pluginInterfacetypes = plugin.GetType().GetInterfaces().Where(a => typeof(IPlugin).IsAssignableFrom(a)).ToArray();
foreach (var type in pluginInterfacetypes)
{
var pairs = new List<string>();
var methodInfos = type.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly);
foreach (var methodInfo in methodInfos)
{
if (methodInfo.GetParameters().Length == 2 && typeof(PluginEventArgs).IsAssignableFrom(methodInfo.GetParameters()[1].ParameterType) && methodInfo.ReturnType == typeof(Task))
{
var name = methodInfo.GetName();
if (pairs.Contains(name))
{
throw new Exception("插件的接口方法不允许重载");
}
if (!pluginMethodNames.Contains(name))
{
pluginMethodNames.Add(name);
}
pairs.Add(name);
}
}
}
return pluginMethodNames;
}
object IPluginsManager.Add(Type pluginType)
object IPluginManager.Add(Type pluginType)
{
if (pluginType.GetCustomAttribute<PluginOptionAttribute>() is PluginOptionAttribute optionAttribute)
{
@@ -164,20 +108,20 @@ namespace ThingsGateway.Foundation.Core
}
}
IPlugin plugin;
if (this.m_container.IsRegistered(pluginType))
if (this.m_resolver.IsRegistered(pluginType))
{
plugin = (IPlugin)this.m_container.Resolve(pluginType);
plugin = (IPlugin)this.m_resolver.Resolve(pluginType);
}
else
{
plugin = (IPlugin)this.m_container.ResolveWithoutRoot(pluginType);
plugin = (IPlugin)this.m_resolver.ResolveWithoutRoot(pluginType);
}
((IPluginsManager)this).Add(plugin);
((IPluginManager)this).Add(plugin);
return plugin;
}
void IPluginsManager.Add(string name, Func<object, PluginEventArgs, Task> func)
void IPluginManager.Add(string name, Func<object, PluginEventArgs, Task> func)
{
lock (this.m_locker)
{
@@ -186,7 +130,17 @@ namespace ThingsGateway.Foundation.Core
}
}
bool IPluginsManager.Raise(string name, object sender, PluginEventArgs e)
/// <inheritdoc/>
public int GetPluginCount(string name)
{
if (this.m_pluginMethods.TryGetValue(name, out var pluginModel))
{
return pluginModel.Funcs.Count;
}
return 0;
}
bool IPluginManager.Raise(string name, object sender, PluginEventArgs e)
{
if (!this.Enable)
{
@@ -201,7 +155,7 @@ namespace ThingsGateway.Foundation.Core
return false;
}
async Task<bool> IPluginsManager.RaiseAsync(string name, object sender, PluginEventArgs e)
async Task<bool> IPluginManager.RaiseAsync(string name, object sender, PluginEventArgs e)
{
if (!this.Enable)
{
@@ -240,14 +194,34 @@ namespace ThingsGateway.Foundation.Core
return pluginModel;
}
/// <inheritdoc/>
public int GetPluginCount(string name)
private List<string> SearchPluginMethod(IPlugin plugin)
{
if (this.m_pluginMethods.TryGetValue(name, out var pluginModel))
var pluginMethodNames = new List<string>();
var pluginInterfacetypes = plugin.GetType().GetInterfaces().Where(a => typeof(IPlugin).IsAssignableFrom(a)).ToArray();
foreach (var type in pluginInterfacetypes)
{
return pluginModel.Funcs.Count;
var pairs = new List<string>();
var methodInfos = type.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly);
foreach (var methodInfo in methodInfos)
{
if (methodInfo.GetParameters().Length == 2 && typeof(PluginEventArgs).IsAssignableFrom(methodInfo.GetParameters()[1].ParameterType) && methodInfo.ReturnType == typeof(Task))
{
var name = methodInfo.GetName();
if (pairs.Contains(name))
{
throw new Exception("插件的接口方法不允许重载");
}
if (!pluginMethodNames.Contains(name))
{
pluginMethodNames.Add(name);
}
pairs.Add(name);
}
}
}
return 0;
return pluginMethodNames;
}
}
}

View File

@@ -0,0 +1,33 @@
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在XREF结尾的命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// API首页http://rrqm_home.gitee.io/touchsocket/
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
#if NET6_0_OR_GREATER
using System.Diagnostics.CodeAnalysis;
#endif
namespace ThingsGateway.Foundation.Core
{
/// <summary>
/// PluginManagerContainerExtension
/// </summary>
public static class PluginManagerContainerExtension
{
/// <summary>
/// 添加<see cref="IPluginManager"/>到容器。
/// </summary>
/// <param name="registrator"></param>
/// <returns></returns>
public static IRegistrator AddPluginManager(this IRegistrator registrator)
{
registrator.RegisterSingleton<IPluginManager, PluginManager>();
return registrator;
}
}
}

View File

@@ -28,16 +28,16 @@ namespace ThingsGateway.Foundation.Core
/// <summary>
/// PluginsManagerExtension
/// </summary>
public static class PluginsManagerExtension
public static class PluginManagerExtension
{
/// <summary>
/// 添加插件
/// </summary>
/// <typeparam name="TPlugin">插件类型</typeparam>
/// <returns>插件类型实例</returns>
public static TPlugin Add<TPlugin>(this IPluginsManager pluginsManager) where TPlugin : class, IPlugin
public static TPlugin Add<TPlugin>(this IPluginManager pluginManager) where TPlugin : class, IPlugin
{
return (TPlugin)pluginsManager.Add(typeof(TPlugin));
return (TPlugin)pluginManager.Add(typeof(TPlugin));
}
/// <summary>
@@ -45,57 +45,57 @@ namespace ThingsGateway.Foundation.Core
/// </summary>
/// <typeparam name="TSender"></typeparam>
/// <typeparam name="TEventArgs"></typeparam>
/// <param name="pluginsManager"></param>
/// <param name="pluginManager"></param>
/// <param name="name"></param>
/// <param name="func"></param>
public static void Add<TSender, TEventArgs>(this IPluginsManager pluginsManager, string name, Func<TSender, TEventArgs, Task> func) where TEventArgs : PluginEventArgs
public static void Add<TSender, TEventArgs>(this IPluginManager pluginManager, string name, Func<TSender, TEventArgs, Task> func) where TEventArgs : PluginEventArgs
{
Task newFunc(object sender, TouchSocketEventArgs e)
{
return func((TSender)sender, (TEventArgs)e);
}
pluginsManager.Add(name, newFunc);
pluginManager.Add(name, newFunc);
}
/// <summary>
/// 添加插件委托
/// </summary>
/// <typeparam name="TEventArgs"></typeparam>
/// <param name="pluginsManager"></param>
/// <param name="pluginManager"></param>
/// <param name="name"></param>
/// <param name="func"></param>
public static void Add<TEventArgs>(this IPluginsManager pluginsManager, string name, Func<TEventArgs, Task> func) where TEventArgs : PluginEventArgs
public static void Add<TEventArgs>(this IPluginManager pluginManager, string name, Func<TEventArgs, Task> func) where TEventArgs : PluginEventArgs
{
Task newFunc(object sender, TouchSocketEventArgs e)
{
return func((TEventArgs)e);
}
pluginsManager.Add(name, newFunc);
pluginManager.Add(name, newFunc);
}
/// <summary>
/// 添加插件委托
/// </summary>
/// <param name="pluginsManager"></param>
/// <param name="pluginManager"></param>
/// <param name="name"></param>
/// <param name="func"></param>
public static void Add(this IPluginsManager pluginsManager, string name, Func<Task> func)
public static void Add(this IPluginManager pluginManager, string name, Func<Task> func)
{
async Task newFunc(object sender, PluginEventArgs e)
{
await func();
await e.InvokeNext();
}
pluginsManager.Add(name, newFunc);
pluginManager.Add(name, newFunc);
}
/// <summary>
/// 添加插件委托
/// </summary>
/// <param name="pluginsManager"></param>
/// <param name="pluginManager"></param>
/// <param name="name"></param>
/// <param name="action"></param>
public static void Add<T>(this IPluginsManager pluginsManager, string name, Action<T> action) where T : class
public static void Add<T>(this IPluginManager pluginManager, string name, Action<T> action) where T : class
{
if (typeof(PluginEventArgs).IsAssignableFrom(typeof(T)))
{
@@ -104,7 +104,7 @@ namespace ThingsGateway.Foundation.Core
action(e as T);
await e.InvokeNext();
}
pluginsManager.Add(name, newFunc);
pluginManager.Add(name, newFunc);
}
else
{
@@ -113,24 +113,24 @@ namespace ThingsGateway.Foundation.Core
action((T)sender);
await e.InvokeNext();
}
pluginsManager.Add(name, newFunc);
pluginManager.Add(name, newFunc);
}
}
/// <summary>
/// 添加插件委托
/// </summary>
/// <param name="pluginsManager"></param>
/// <param name="pluginManager"></param>
/// <param name="name"></param>
/// <param name="action"></param>
public static void Add(this IPluginsManager pluginsManager, string name, Action action)
public static void Add(this IPluginManager pluginManager, string name, Action action)
{
async Task newFunc(object sender, PluginEventArgs e)
{
action();
await e.InvokeNext();
}
pluginsManager.Add(name, newFunc);
pluginManager.Add(name, newFunc);
}
}
}

View File

@@ -32,13 +32,8 @@ namespace ThingsGateway.Foundation.Core
public sealed class PluginOptionAttribute : Attribute
{
/// <summary>
/// 标识该插件在一个<see cref="IPluginsManager"/>中仅仅只会有一个实例。
/// 标识该插件在一个<see cref="IPluginManager"/>中仅仅只会有一个实例。
/// </summary>
public bool Singleton { get; set; }
/// <summary>
/// 标识该插件不需要注册到容器。可能是功能性插件。
/// </summary>
public bool NotRegister { get; set; }
}
}

View File

@@ -10,12 +10,8 @@
//------------------------------------------------------------------------------
#endregion
using System.Collections;
using System.Linq.Expressions;
namespace ThingsGateway.Foundation.Core
{
#if NET6_0_OR_GREATER
/// <summary>
/// 实例生成
/// </summary>
@@ -25,42 +21,12 @@ namespace ThingsGateway.Foundation.Core
/// 根据对象类型创建对象实例
/// </summary>
/// <param name="key">对象类型</param>
/// <param name="args"></param>
/// <returns></returns>
public static object Create(Type key)
public static object Create(Type key, object[] args)
{
return Activator.CreateInstance(key);
}
}
#else
/// <summary>
/// 实例生成
/// </summary>
public static class InstanceCreater
{
private static readonly Hashtable m_paramCache = Hashtable.Synchronized(new Hashtable());//缓存
/// <summary>
/// 根据对象类型创建对象实例
/// </summary>
/// <param name="key">对象类型</param>
/// <returns></returns>
public static object Create(Type key)
{
var value = (Func<object>)m_paramCache[key];
if (value == null)
{
value = CreateInstanceByType(key);
m_paramCache[key] = value;
}
return value();
}
private static Func<object> CreateInstanceByType(Type type)
{
return Expression.Lambda<Func<object>>(Expression.New(type), null).Compile();
return Activator.CreateInstance(key, args);
}
}
#endif
}

View File

@@ -184,9 +184,9 @@ namespace ThingsGateway.Foundation.Dmtp
{
if (!await this.m_dmtpActor.InputReceivedData(message))
{
if (this.PluginsManager.Enable)
if (this.PluginManager.Enable)
{
await this.PluginsManager.RaiseAsync(nameof(IDmtpReceivedPlugin.OnDmtpReceived), this, new DmtpMessageEventArgs(message));
await this.PluginManager.RaiseAsync(nameof(IDmtpReceivedPlugin.OnDmtpReceived), this, new DmtpMessageEventArgs(message));
}
}
return;
@@ -198,10 +198,10 @@ namespace ThingsGateway.Foundation.Dmtp
protected override void LoadConfig(TouchSocketConfig config)
{
base.LoadConfig(config);
if (this.Container.IsRegistered(typeof(IDmtpRouteService)))
if (this.Resolver.IsRegistered(typeof(IDmtpRouteService)))
{
this.m_allowRoute = true;
this.m_findDmtpActor = this.Container.Resolve<IDmtpRouteService>().FindDmtpActor;
this.m_findDmtpActor = this.Resolver.Resolve<IDmtpRouteService>().FindDmtpActor;
}
}
@@ -294,7 +294,7 @@ namespace ThingsGateway.Foundation.Dmtp
return;
}
await this.PluginsManager.RaiseAsync(nameof(IDmtpCreateChannelPlugin.OnCreateChannel), this, e);
await this.PluginManager.RaiseAsync(nameof(IDmtpCreateChannelPlugin.OnCreateChannel), this, e);
}
/// <summary>
@@ -307,7 +307,7 @@ namespace ThingsGateway.Foundation.Dmtp
{
return;
}
await this.PluginsManager.RaiseAsync(nameof(IDmtpHandshakedPlugin.OnDmtpHandshaked), this, e);
await this.PluginManager.RaiseAsync(nameof(IDmtpHandshakedPlugin.OnDmtpHandshaked), this, e);
}
/// <summary>
@@ -320,7 +320,7 @@ namespace ThingsGateway.Foundation.Dmtp
{
return;
}
await this.PluginsManager.RaiseAsync(nameof(IDmtpHandshakingPlugin.OnDmtpHandshaking), this, e);
await this.PluginManager.RaiseAsync(nameof(IDmtpHandshakingPlugin.OnDmtpHandshaking), this, e);
}
/// <summary>
@@ -333,7 +333,7 @@ namespace ThingsGateway.Foundation.Dmtp
{
return;
}
await this.PluginsManager.RaiseAsync(nameof(IDmtpRoutingPlugin.OnDmtpRouting), this, e);
await this.PluginManager.RaiseAsync(nameof(IDmtpRoutingPlugin.OnDmtpRouting), this, e);
}
#endregion

View File

@@ -54,10 +54,10 @@ namespace ThingsGateway.Foundation.Dmtp
protected override void LoadConfig(TouchSocketConfig config)
{
base.LoadConfig(config);
if (this.Container.IsRegistered(typeof(IDmtpRouteService)))
if (this.Resolver.IsRegistered(typeof(IDmtpRouteService)))
{
this.m_allowRoute = true;
this.m_findDmtpActor = this.Container.Resolve<IDmtpRouteService>().FindDmtpActor;
this.m_findDmtpActor = this.Resolver.Resolve<IDmtpRouteService>().FindDmtpActor;
}
}

View File

@@ -135,7 +135,7 @@ namespace ThingsGateway.Foundation.Dmtp
{
if (!await this.m_dmtpActor.InputReceivedData(message))
{
await this.PluginsManager.RaiseAsync(nameof(IDmtpReceivedPlugin.OnDmtpReceived), this, new DmtpMessageEventArgs(message));
await this.PluginManager.RaiseAsync(nameof(IDmtpReceivedPlugin.OnDmtpReceived), this, new DmtpMessageEventArgs(message));
}
}
await base.ReceivedData(e);
@@ -228,7 +228,7 @@ namespace ThingsGateway.Foundation.Dmtp
return;
}
await this.PluginsManager.RaiseAsync(nameof(IDmtpCreateChannelPlugin.OnCreateChannel), this, e);
await this.PluginManager.RaiseAsync(nameof(IDmtpCreateChannelPlugin.OnCreateChannel), this, e);
}
/// <summary>
@@ -241,7 +241,7 @@ namespace ThingsGateway.Foundation.Dmtp
{
return;
}
await this.PluginsManager.RaiseAsync(nameof(IDmtpHandshakedPlugin.OnDmtpHandshaked), this, e);
await this.PluginManager.RaiseAsync(nameof(IDmtpHandshakedPlugin.OnDmtpHandshaked), this, e);
}
/// <summary>
@@ -254,7 +254,7 @@ namespace ThingsGateway.Foundation.Dmtp
{
return;
}
await this.PluginsManager.RaiseAsync(nameof(IDmtpHandshakingPlugin.OnDmtpHandshaking), this, e);
await this.PluginManager.RaiseAsync(nameof(IDmtpHandshakingPlugin.OnDmtpHandshaking), this, e);
}
/// <summary>
@@ -267,7 +267,7 @@ namespace ThingsGateway.Foundation.Dmtp
{
return;
}
await this.PluginsManager.RaiseAsync(nameof(IDmtpRoutingPlugin.OnDmtpRouting), this, e);
await this.PluginManager.RaiseAsync(nameof(IDmtpRoutingPlugin.OnDmtpRouting), this, e);
}
#endregion

View File

@@ -219,10 +219,10 @@ namespace ThingsGateway.Foundation.Dmtp
{
config.SetTcpDataHandlingAdapter(() => new TcpDmtpAdapter());
base.LoadConfig(config);
if (this.Container.IsRegistered(typeof(IDmtpRouteService)))
if (this.Resolver.IsRegistered(typeof(IDmtpRouteService)))
{
this.m_allowRoute = true;
this.m_findDmtpActor = this.Container.Resolve<IDmtpRouteService>().FindDmtpActor;
this.m_findDmtpActor = this.Resolver.Resolve<IDmtpRouteService>().FindDmtpActor;
}
this.m_dmtpActor = new SealedDmtpActor(this.m_allowRoute)
{
@@ -245,7 +245,7 @@ namespace ThingsGateway.Foundation.Dmtp
var message = (DmtpMessage)e.RequestInfo;
if (!await this.m_dmtpActor.InputReceivedData(message).ConfigureFalseAwait())
{
await this.PluginsManager.RaiseAsync(nameof(IDmtpReceivedPlugin.OnDmtpReceived), this, new DmtpMessageEventArgs(message)).ConfigureFalseAwait();
await this.PluginManager.RaiseAsync(nameof(IDmtpReceivedPlugin.OnDmtpReceived), this, new DmtpMessageEventArgs(message)).ConfigureFalseAwait();
}
await base.ReceivedData(e).ConfigureFalseAwait();
@@ -304,7 +304,7 @@ namespace ThingsGateway.Foundation.Dmtp
return;
}
await this.PluginsManager.RaiseAsync(nameof(IDmtpCreateChannelPlugin.OnCreateChannel), this, e).ConfigureFalseAwait();
await this.PluginManager.RaiseAsync(nameof(IDmtpCreateChannelPlugin.OnCreateChannel), this, e).ConfigureFalseAwait();
}
/// <summary>
@@ -317,7 +317,7 @@ namespace ThingsGateway.Foundation.Dmtp
{
return;
}
await this.PluginsManager.RaiseAsync(nameof(IDmtpHandshakedPlugin.OnDmtpHandshaked), this, e).ConfigureFalseAwait();
await this.PluginManager.RaiseAsync(nameof(IDmtpHandshakedPlugin.OnDmtpHandshaked), this, e).ConfigureFalseAwait();
}
/// <summary>
@@ -330,7 +330,7 @@ namespace ThingsGateway.Foundation.Dmtp
{
return;
}
await this.PluginsManager.RaiseAsync(nameof(IDmtpHandshakingPlugin.OnDmtpHandshaking), this, e).ConfigureFalseAwait();
await this.PluginManager.RaiseAsync(nameof(IDmtpHandshakingPlugin.OnDmtpHandshaking), this, e).ConfigureFalseAwait();
}
/// <summary>
@@ -343,7 +343,7 @@ namespace ThingsGateway.Foundation.Dmtp
{
return;
}
await this.PluginsManager.RaiseAsync(nameof(IDmtpRoutingPlugin.OnDmtpRouting), this, e).ConfigureFalseAwait();
await this.PluginManager.RaiseAsync(nameof(IDmtpRoutingPlugin.OnDmtpRouting), this, e).ConfigureFalseAwait();
}
#endregion

View File

@@ -56,10 +56,10 @@ namespace ThingsGateway.Foundation.Dmtp
config.SetTcpDataHandlingAdapter(() => new TcpDmtpAdapter());
base.LoadConfig(config);
if (this.Container.IsRegistered(typeof(IDmtpRouteService)))
if (this.Resolver.IsRegistered(typeof(IDmtpRouteService)))
{
this.m_allowRoute = true;
this.m_findDmtpActor = this.Container.Resolve<IDmtpRouteService>().FindDmtpActor;
this.m_findDmtpActor = this.Resolver.Resolve<IDmtpRouteService>().FindDmtpActor;
}
}

View File

@@ -108,7 +108,7 @@ namespace ThingsGateway.Foundation.Dmtp
return;
}
await this.PluginsManager.RaiseAsync(nameof(IDmtpCreateChannelPlugin.OnCreateChannel), this, e).ConfigureFalseAwait();
await this.PluginManager.RaiseAsync(nameof(IDmtpCreateChannelPlugin.OnCreateChannel), this, e).ConfigureFalseAwait();
}
/// <summary>
@@ -121,7 +121,7 @@ namespace ThingsGateway.Foundation.Dmtp
{
return;
}
await this.PluginsManager.RaiseAsync(nameof(IDmtpHandshakedPlugin.OnDmtpHandshaked), this, e).ConfigureFalseAwait();
await this.PluginManager.RaiseAsync(nameof(IDmtpHandshakedPlugin.OnDmtpHandshaked), this, e).ConfigureFalseAwait();
}
/// <summary>
@@ -134,7 +134,7 @@ namespace ThingsGateway.Foundation.Dmtp
{
return;
}
await this.PluginsManager.RaiseAsync(nameof(IDmtpHandshakingPlugin.OnDmtpHandshaking), this, e).ConfigureFalseAwait();
await this.PluginManager.RaiseAsync(nameof(IDmtpHandshakingPlugin.OnDmtpHandshaking), this, e).ConfigureFalseAwait();
}
/// <summary>
@@ -147,7 +147,7 @@ namespace ThingsGateway.Foundation.Dmtp
{
return;
}
await this.PluginsManager.RaiseAsync(nameof(IDmtpRoutingPlugin.OnDmtpRouting), this, e);
await this.PluginManager.RaiseAsync(nameof(IDmtpRoutingPlugin.OnDmtpRouting), this, e);
}
#endregion
@@ -228,7 +228,7 @@ namespace ThingsGateway.Foundation.Dmtp
var message = (DmtpMessage)e.RequestInfo;
if (!await this.m_dmtpActor.InputReceivedData(message).ConfigureFalseAwait())
{
await this.PluginsManager.RaiseAsync(nameof(IDmtpReceivedPlugin.OnDmtpReceived), this, new DmtpMessageEventArgs(message)).ConfigureFalseAwait();
await this.PluginManager.RaiseAsync(nameof(IDmtpReceivedPlugin.OnDmtpReceived), this, new DmtpMessageEventArgs(message)).ConfigureFalseAwait();
}
await base.ReceivedData(e).ConfigureFalseAwait();
}

View File

@@ -86,9 +86,9 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
var message = DmtpMessage.CreateFrom(e.ByteBlock);
if (!await client.InputReceivedData(message))
{
if (this.PluginsManager.Enable)
if (this.PluginManager.Enable)
{
await this.PluginsManager.RaiseAsync(nameof(IDmtpReceivedPlugin.OnDmtpReceived), client, new DmtpMessageEventArgs(message));
await this.PluginManager.RaiseAsync(nameof(IDmtpReceivedPlugin.OnDmtpReceived), client, new DmtpMessageEventArgs(message));
}
}
}
@@ -103,11 +103,11 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
{
if (!this.m_udpDmtpClients.TryGetValue(endPoint, out var udpRpcActor))
{
udpRpcActor = new UdpDmtpClient(this, endPoint, this.Container.Resolve<ILog>())
udpRpcActor = new UdpDmtpClient(this, endPoint, this.Resolver.Resolve<ILog>())
{
Client = this,
};
if (udpRpcActor.Created(this.PluginsManager))
if (udpRpcActor.Created(this.PluginManager))
{
this.m_udpDmtpClients.TryAdd(endPoint, udpRpcActor);
}

View File

@@ -33,7 +33,7 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
{
private readonly EndPoint m_endPoint;
private readonly UdpSessionBase m_udpSession;
private IPluginsManager pluginsManager;
private IPluginManager pluginManager;
/// <summary>
/// UdpDmtp终端客户端
@@ -55,18 +55,18 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
private Task OnDmtpActorCreatedChannel(DmtpActor actor, CreateChannelEventArgs e)
{
return this.pluginsManager.RaiseAsync(nameof(IDmtpCreateChannelPlugin.OnCreateChannel), this, e);
return this.pluginManager.RaiseAsync(nameof(IDmtpCreateChannelPlugin.OnCreateChannel), this, e);
}
public bool Created(IPluginsManager pluginsManager)
public bool Created(IPluginManager pluginManager)
{
this.pluginsManager = pluginsManager;
this.pluginManager = pluginManager;
var args = new DmtpVerifyEventArgs()
{
Id = this.Id,
IsPermitOperation = true
};
pluginsManager.Raise(nameof(IDmtpHandshakingPlugin.OnDmtpHandshaking), this, args);
pluginManager.Raise(nameof(IDmtpHandshakingPlugin.OnDmtpHandshaking), this, args);
if (args.IsPermitOperation == false)
{
@@ -79,7 +79,7 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
{
Id = this.Id
};
pluginsManager.Raise(nameof(IDmtpHandshakedPlugin.OnDmtpHandshaked), this, args);
pluginManager.Raise(nameof(IDmtpHandshakedPlugin.OnDmtpHandshaked), this, args);
return true;
}

View File

@@ -205,9 +205,9 @@ namespace ThingsGateway.Foundation.Dmtp
protected override void LoadConfig(TouchSocketConfig config)
{
this.RemoteIPHost = config.GetValue(TouchSocketConfigExtension.RemoteIPHostProperty);
if (this.Container.IsRegistered(typeof(IDmtpRouteService)))
if (this.Resolver.IsRegistered(typeof(IDmtpRouteService)))
{
this.m_findDmtpActor = this.Container.Resolve<IDmtpRouteService>().FindDmtpActor;
this.m_findDmtpActor = this.Resolver.Resolve<IDmtpRouteService>().FindDmtpActor;
}
}
@@ -217,7 +217,7 @@ namespace ThingsGateway.Foundation.Dmtp
/// <param name="e"></param>
protected virtual void OnDisconnected(DisconnectEventArgs e)
{
if (this.PluginsManager.Raise(nameof(ITcpDisconnectedPlugin.OnTcpDisconnected), this, e))
if (this.PluginManager.Raise(nameof(ITcpDisconnectedPlugin.OnTcpDisconnected), this, e))
{
return;
}
@@ -289,7 +289,7 @@ namespace ThingsGateway.Foundation.Dmtp
var message = (DmtpMessage)requestInfo;
if (!this.m_dmtpActor.InputReceivedData(message).GetFalseAwaitResult())
{
this.PluginsManager?.Raise(nameof(IDmtpReceivedPlugin.OnDmtpReceived), this, new DmtpMessageEventArgs(message));
this.PluginManager?.Raise(nameof(IDmtpReceivedPlugin.OnDmtpReceived), this, new DmtpMessageEventArgs(message));
}
}
@@ -387,7 +387,7 @@ namespace ThingsGateway.Foundation.Dmtp
return;
}
await this.PluginsManager.RaiseAsync(nameof(IDmtpCreateChannelPlugin.OnCreateChannel), this, e);
await this.PluginManager.RaiseAsync(nameof(IDmtpCreateChannelPlugin.OnCreateChannel), this, e);
}
/// <summary>
@@ -400,7 +400,7 @@ namespace ThingsGateway.Foundation.Dmtp
{
return;
}
await this.PluginsManager.RaiseAsync(nameof(IDmtpHandshakedPlugin.OnDmtpHandshaked), this, e);
await this.PluginManager.RaiseAsync(nameof(IDmtpHandshakedPlugin.OnDmtpHandshaked), this, e);
}
/// <summary>
@@ -413,7 +413,7 @@ namespace ThingsGateway.Foundation.Dmtp
{
return;
}
await this.PluginsManager.RaiseAsync(nameof(IDmtpHandshakingPlugin.OnDmtpHandshaking), this, e);
await this.PluginManager.RaiseAsync(nameof(IDmtpHandshakingPlugin.OnDmtpHandshaking), this, e);
}
/// <summary>
@@ -426,7 +426,7 @@ namespace ThingsGateway.Foundation.Dmtp
{
return;
}
await this.PluginsManager.RaiseAsync(nameof(IDmtpRoutingPlugin.OnDmtpRouting), this, e);
await this.PluginManager.RaiseAsync(nameof(IDmtpRoutingPlugin.OnDmtpRouting), this, e);
}
#endregion

View File

@@ -28,7 +28,7 @@ namespace ThingsGateway.Foundation.Dmtp
/// <summary>
/// DmtpPluginsManagerExtension
/// </summary>
public static class DmtpPluginsManagerExtension
public static class DmtpPluginManagerExtension
{
/// <summary>
/// DmtpRpc心跳。客户端、服务器均但是一般建议仅客户端使用即可。
@@ -36,12 +36,12 @@ namespace ThingsGateway.Foundation.Dmtp
/// 默认心跳每3秒进行一次。最大失败3次即判定为断开连接。
/// </para>
/// </summary>
/// <param name="pluginsManager"></param>
/// <param name="pluginManager"></param>
/// <returns></returns>
public static DmtpHeartbeatPlugin UseDmtpHeartbeat(this IPluginsManager pluginsManager)
public static DmtpHeartbeatPlugin UseDmtpHeartbeat(this IPluginManager pluginManager)
{
var heartbeat = new DmtpHeartbeatPlugin();
pluginsManager.Add(heartbeat);
pluginManager.Add(heartbeat);
return heartbeat;
}
}

View File

@@ -18,21 +18,24 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
public sealed class DmtpFileTransferFeature : PluginBase, IDmtpHandshakingPlugin, IDmtpReceivedPlugin, IDmtpFeature
{
private readonly IFileResourceController m_fileResourceController;
private readonly IPluginsManager m_pluginsManager;
private IPluginManager m_pluginManager;
/// <summary>
/// 能够基于Dmtp协议提供文件传输的能力
/// </summary>
/// <param name="pluginsManager"></param>
/// <param name="container"></param>
public DmtpFileTransferFeature(IPluginsManager pluginsManager, IContainer container)
/// <param name="resolver"></param>
public DmtpFileTransferFeature(IResolver resolver)
{
this.m_fileResourceController = container.TryResolve<IFileResourceController>() ?? new FileResourceController();
this.m_pluginsManager = pluginsManager;
this.m_fileResourceController = resolver.TryResolve<IFileResourceController>() ?? new FileResourceController();
this.MaxSmallFileLength = 1024 * 1024;
this.SetProtocolFlags(30);
}
/// <inheritdoc/>
protected override void Loaded(IPluginManager pluginManager)
{
base.Loaded(pluginManager);
this.m_pluginManager = pluginManager;
}
/// <inheritdoc cref="IDmtpFileTransferActor.MaxSmallFileLength"/>
public int MaxSmallFileLength { get; set; }
@@ -107,12 +110,12 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
private Task OnFileTransfered(IDmtpActor actor, FileTransferedEventArgs e)
{
return this.m_pluginsManager.RaiseAsync(nameof(IDmtpFileTransferedPlugin<IDmtpActorObject>.OnDmtpFileTransfered), actor.Client, e);
return this.m_pluginManager.RaiseAsync(nameof(IDmtpFileTransferedPlugin<IDmtpActorObject>.OnDmtpFileTransfered), actor.Client, e);
}
private Task OnFileTransfering(IDmtpActor actor, FileTransferingEventArgs e)
{
return this.m_pluginsManager.RaiseAsync(nameof(IDmtpFileTransferingPlugin<IDmtpActorObject>.OnDmtpFileTransfering), actor.Client, e);
return this.m_pluginManager.RaiseAsync(nameof(IDmtpFileTransferingPlugin<IDmtpActorObject>.OnDmtpFileTransfering), actor.Client, e);
}
}
}

View File

@@ -26,11 +26,11 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
/// <summary>
/// 使用DmtpFileTransfer插件
/// </summary>
/// <param name="pluginsManager"></param>
/// <param name="pluginManager"></param>
/// <returns></returns>
public static DmtpFileTransferFeature UseDmtpFileTransfer(this IPluginsManager pluginsManager)
public static DmtpFileTransferFeature UseDmtpFileTransfer(this IPluginManager pluginManager)
{
return pluginsManager.Add<DmtpFileTransferFeature>();
return pluginManager.Add<DmtpFileTransferFeature>();
}
#endregion

Some files were not shown because too many files have changed in this diff Show More