Compare commits
10 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
99eef8fb28 | ||
|
|
47e7685d39 | ||
|
|
b6ea596ade | ||
|
|
44d60b469b | ||
|
|
51087408df | ||
|
|
96226d9e6e | ||
|
|
28f0f62424 | ||
|
|
2e772a8cd4 | ||
|
|
3fd192f0cf | ||
|
|
d16ae81961 |
@@ -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>
|
||||
|
||||
@@ -24,7 +24,6 @@ public class Startup : AppStartup
|
||||
public void ConfigureServices(IServiceCollection services)
|
||||
{
|
||||
services.ThingsGatewayComponentsConfigureServices();
|
||||
|
||||
services.AddScoped<UserResoures>();
|
||||
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>();
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
|
||||
namespace ThingsGateway.Components
|
||||
{
|
||||
public interface IDefaultTimezoneOffsetAccessor
|
||||
{
|
||||
TimeSpan GetTimezoneOffsetResult();
|
||||
}
|
||||
}
|
||||
@@ -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客户端时差
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Masa.Blazor" Version="1.2.2" />
|
||||
<PackageReference Include="Masa.Blazor.SomethingSkia" Version="1.2.2" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
{
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
{
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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;
|
||||
|
||||
//初始化
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace ThingsGateway.Foundation.Demo;
|
||||
public partial class DLT645_2007OverTcpDebugPage
|
||||
{
|
||||
/// <summary>
|
||||
/// SerialSessionPage
|
||||
/// SerialPortClientPage
|
||||
/// </summary>
|
||||
private TcpClientPage _tcpClientPage;
|
||||
private DriverDebugUIPage _driverDebugUIPage;
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace ThingsGateway.Foundation.Demo;
|
||||
public partial class ModbusRtuOverTcpDebugPage
|
||||
{
|
||||
/// <summary>
|
||||
/// SerialSessionPage
|
||||
/// SerialPortClientPage
|
||||
/// </summary>
|
||||
private TcpClientPage _tcpClientPage;
|
||||
private DriverDebugUIPage _driverDebugUIPage;
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace ThingsGateway.Foundation.Demo;
|
||||
public partial class ModbusRtuOverUdpDebugPage
|
||||
{
|
||||
/// <summary>
|
||||
/// SerialSessionPage
|
||||
/// SerialPortClientPage
|
||||
/// </summary>
|
||||
private UdpSessionPage _udpSessionPage;
|
||||
private DriverDebugUIPage _driverDebugUIPage;
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -21,7 +21,7 @@ public partial class ModbusTcpDebugPage
|
||||
private ThingsGateway.Foundation.Adapter.Modbus.ModbusTcp _plc;
|
||||
|
||||
/// <summary>
|
||||
/// SerialSessionPage
|
||||
/// SerialPortClientPage
|
||||
/// </summary>
|
||||
private TcpClientPage _tcpClientPage;
|
||||
/// <summary>
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace ThingsGateway.Foundation.Demo;
|
||||
public partial class ModbusUdpDebugPage
|
||||
{
|
||||
/// <summary>
|
||||
/// SerialSessionPage
|
||||
/// SerialPortClientPage
|
||||
/// </summary>
|
||||
private UdpSessionPage _udpSessionPage;
|
||||
private DriverDebugUIPage _driverDebugUIPage;
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ public partial class SiemensDebugPage
|
||||
private ThingsGateway.Foundation.Adapter.Siemens.SiemensS7PLC _plc;
|
||||
|
||||
/// <summary>
|
||||
/// SerialSessionPage
|
||||
/// SerialPortClientPage
|
||||
/// </summary>
|
||||
private TcpClientPage _tcpClientPage;
|
||||
/// <summary>
|
||||
|
||||
@@ -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"
|
||||
// }
|
||||
// ]
|
||||
//}
|
||||
]
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
@@ -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();
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
<UseWindowsForms>true</UseWindowsForms>
|
||||
</PropertyGroup>
|
||||
|
||||
|
||||
<ItemGroup>
|
||||
<None Remove="favicon.ico" />
|
||||
</ItemGroup>
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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/>
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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/>
|
||||
|
||||
@@ -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/>
|
||||
|
||||
@@ -22,7 +22,7 @@ public enum ChannelEnum
|
||||
/// <inheritdoc/>
|
||||
TcpClient = 1,
|
||||
/// <inheritdoc/>
|
||||
SerialSession = 2,
|
||||
SerialPortClient = 2,
|
||||
/// <inheritdoc/>
|
||||
UdpSession = 4,
|
||||
/// <inheritdoc/>
|
||||
|
||||
@@ -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; }
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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}]";
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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>
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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; }
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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; }
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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时间格式字符串
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
/// 添加插件异步执行委托
|
||||
@@ -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; }
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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; }
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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 事件触发
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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 事件
|
||||
|
||||
@@ -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 事件触发
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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 事件触发
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
Reference in New Issue
Block a user