提交 465e4a91 编写于 作者: 若汝棋茗

优化Mapper,新增端口复用

上级 8545b659
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using TouchSocket.Core.Reflection;
namespace TouchSocketPro
{
......@@ -11,102 +14,97 @@ namespace TouchSocketPro
/// </summary>
public static class Mapper
{
private static readonly ConcurrentDictionary<Type, Dictionary<string, Property>> m_typeToProperty = new ConcurrentDictionary<Type, Dictionary<string, Property>>();
/// <summary>
/// 简单映射
/// </summary>
/// <typeparam name="T"></typeparam>
/// <typeparam name="T1"></typeparam>
/// <param name="t"></param>
/// <typeparam name="TTarget"></typeparam>
/// <param name="source"></param>
/// <returns></returns>
public static T1 Map<T, T1>(T t)where T:class where T1:class,new ()
public static TTarget Map<TTarget>(object source) where TTarget : class, new()
{
if (t is null)
{
return default;
}
var source = Activator.CreateInstance(typeof(T));
var result = Activator.CreateInstance(typeof(T1));
if (source.GetType().Name == "List`1" || result.GetType().Name == "List`1")
{
throw new Exception("形参有误!,请使用对象。");
}
var tpropertyInfos = source.GetType().GetProperties();
var t1propertyInfos = result.GetType().GetProperties();
foreach (var tinfo in tpropertyInfos)
{
foreach (var t1info in t1propertyInfos)
{
if (t1info.PropertyType.IsValueType || t1info.PropertyType.Name.StartsWith("String"))
{
if (tinfo.Name == t1info.Name)
{
try
{
object value = tinfo.GetValue(t, null);
var property = typeof(T1).GetProperty(tinfo.Name);
if (property != null && property.CanWrite && !(value is DBNull))
{
property.SetValue(result, value, null);
}
}
catch
{
}
}
}
}
}
return (T1)result;
return (TTarget)Map(source,typeof(TTarget));
}
/// <summary>
/// 简单映射
/// </summary>
/// <typeparam name="T1"></typeparam>
/// <param name="t"></param>
/// <typeparam name="TSource"></typeparam>
/// <typeparam name="TTarget"></typeparam>
/// <param name="source"></param>
/// <returns></returns>
public static T1 Map<T1>(object t) where T1 : class, new()
public static TTarget Map<TSource,TTarget>(TSource source) where TTarget : class, new()
{
if (t is null)
return (TTarget)Map(source, typeof(TTarget));
}
/// <summary>
/// 简单对象映射
/// </summary>
/// <param name="source"></param>
/// <param name="targetType"></param>
/// <returns></returns>
public static object Map(object source,Type targetType)
{
return Map(source, Activator.CreateInstance(targetType));
}
/// <summary>
/// 简单对象映射
/// </summary>
/// <param name="source"></param>
/// <param name="target"></param>
/// <returns></returns>
public static object Map(object source, object target)
{
if (source is null)
{
return default;
}
var result = Activator.CreateInstance(typeof(T1));
if (t.GetType().Name == "List`1" || result.GetType().Name == "List`1")
var sourceType = source.GetType();
if (sourceType.IsPrimitive || sourceType.IsEnum || sourceType == TouchSocket.Core.TouchSocketCoreUtility.stringType)
{
throw new Exception("形参有误!,请使用对象。");
return source;
}
var tpropertyInfos = t.GetType().GetProperties();
var t1propertyInfos = result.GetType().GetProperties();
foreach (var tinfo in tpropertyInfos)
var sourcePairs = m_typeToProperty.GetOrAdd(sourceType, (k) =>
{
Dictionary<string, Property> pairs = new Dictionary<string, Property>();
var ps = k.GetProperties(BindingFlags.Default | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
foreach (var item in ps)
{
pairs.Add(item.Name, new Property(item));
}
return pairs;
});
var targetPairs = m_typeToProperty.GetOrAdd(target.GetType(), (k) =>
{
foreach (var t1info in t1propertyInfos)
Dictionary<string, Property> pairs = new Dictionary<string, Property>();
var ps = k.GetProperties(BindingFlags.Default | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
foreach (var item in ps)
{
if (t1info.PropertyType.IsValueType || t1info.PropertyType.Name.StartsWith("String"))
pairs.Add(item.Name, new Property(item));
}
return pairs;
});
foreach (var item in targetPairs)
{
if (item.Value.CanWrite)
{
if (sourcePairs.TryGetValue(item.Key,out Property property))
{
if (tinfo.Name == t1info.Name)
if (property.CanRead)
{
try
{
object value = tinfo.GetValue(t, null);
var property = typeof(T1).GetProperty(tinfo.Name);
if (property != null && property.CanWrite && !(value is DBNull))
{
property.SetValue(result, value, null);
}
}
catch
{
}
item.Value.SetValue(target,property.GetValue(source));
}
}
}
}
return (T1)result;
return target;
}
/// <summary>
/// 映射List
/// </summary>
......
......@@ -25,12 +25,12 @@ namespace TouchSocket.Core.Reflection
/// <summary>
/// 获取器
/// </summary>
private readonly PropertyGetter geter;
private readonly PropertyGetter m_geter;
/// <summary>
/// 设置器
/// </summary>
private readonly PropertySetter seter;
private readonly PropertySetter m_seter;
/// <summary>
/// 获取属性名称
......@@ -53,14 +53,26 @@ namespace TouchSocket.Core.Reflection
if (property.CanRead == true)
{
this.geter = new PropertyGetter(property);
this.CanRead = true;
this.m_geter = new PropertyGetter(property);
}
if (property.CanWrite == true)
{
this.seter = new PropertySetter(property);
this.CanWrite = true;
this.m_seter = new PropertySetter(property);
}
}
/// <summary>
/// 是否可以读取
/// </summary>
public bool CanRead { get; private set; }
/// <summary>
/// 是否可以写入
/// </summary>
public bool CanWrite { get; private set; }
/// <summary>
/// 获取属性的值
/// </summary>
......@@ -69,11 +81,11 @@ namespace TouchSocket.Core.Reflection
/// <returns></returns>
public object GetValue(object instance)
{
if (this.geter == null)
if (this.m_geter == null)
{
throw new NotSupportedException();
}
return this.geter.Invoke(instance);
return this.m_geter.Invoke(instance);
}
/// <summary>
......@@ -84,11 +96,11 @@ namespace TouchSocket.Core.Reflection
/// <exception cref="NotSupportedException"></exception>
public void SetValue(object instance, object value)
{
if (this.seter == null)
if (this.m_seter == null)
{
throw new NotSupportedException($"{this.Name}不允许赋值");
}
this.seter.Invoke(instance, value);
this.m_seter.Invoke(instance, value);
}
/// <summary>
......
......@@ -688,6 +688,10 @@ namespace TouchSocket.Sockets
socket.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.NoDelay, this.m_config.GetValue<bool>(TouchSocketConfigExtension.NoDelayProperty));
if (this.m_config.GetValue<IPHost>(TouchSocketConfigExtension.BindIPHostProperty) != null)
{
if (this.m_config.GetValue<bool>(TouchSocketConfigExtension.ReuseAddressProperty))
{
socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
}
socket.Bind(this.m_config.GetValue<IPHost>(TouchSocketConfigExtension.BindIPHostProperty).EndPoint);
}
return socket;
......
......@@ -547,6 +547,10 @@ namespace TouchSocket.Sockets
Socket socket = new Socket(iPHost.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
socket.ReceiveBufferSize = this.BufferLength;
socket.SendBufferSize = this.BufferLength;
if (this.m_config.GetValue<bool>(TouchSocketConfigExtension.ReuseAddressProperty))
{
socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
}
this.PreviewBind(socket);
socket.Bind(iPHost.EndPoint);
socket.Listen(this.m_backlog);
......
......@@ -431,6 +431,10 @@ namespace TouchSocket.Sockets
socket.UseOnlyOverlappedIO = true;
}
socket.EnableBroadcast = this.m_config.GetValue<bool>(TouchSocketConfigExtension.EnableBroadcastProperty);
if (this.m_config.GetValue<bool>(TouchSocketConfigExtension.ReuseAddressProperty))
{
socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
}
this.PreviewBind(socket);
socket.Bind(iPHost.EndPoint);
......
......@@ -385,6 +385,24 @@ namespace TouchSocket.Sockets
/// </summary>
public static readonly DependencyProperty MaxCountProperty =
DependencyProperty.Register("MaxCount", typeof(int), typeof(TouchSocketConfigExtension), 10000);
/// <summary>
/// 端口复用,默认为false,所需类型<see cref="bool"/>
/// </summary>
public static readonly DependencyProperty ReuseAddressProperty =
DependencyProperty.Register("ReuseAddress", typeof(bool), typeof(TouchSocketConfigExtension), false);
/// <summary>
/// 启用端口复用。
/// <para>该配置可在服务器、或客户端在监听端口时,运行监听同一个端口。可以一定程度缓解端口来不及释放的问题</para>
/// </summary>
/// <param name="config"></param>
/// <returns></returns>
public static TouchSocketConfig UseReuseAddress(this TouchSocketConfig config)
{
config.SetValue(ReuseAddressProperty, true);
return config;
}
/// <summary>
/// 挂起连接队列的最大长度,默认100。
......
......@@ -4,7 +4,7 @@
<ApplicationIcon>logo.ico</ApplicationIcon>
<SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>RRQM.pfx</AssemblyOriginatorKeyFile>
<Version>0.2.0</Version>
<Version>0.2.1</Version>
<LangVersion>8.0</LangVersion>
<Company>若汝棋茗</Company>
<Copyright>Copyright © 2022 若汝棋茗</Copyright>
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册