shiqian.wang
4 months ago
9 changed files with 658 additions and 10 deletions
-
4ICSSoft.FromERP/App.config
-
120ICSSoft.FromERP/HttpHelper.cs
-
324ICSSoft.FromERP/ICSAddStdWorkHourFromMES.cs
-
50ICSSoft.FromERP/ICSSoft.FromERP.csproj
-
143ICSSoft.FromERP/Singleton.cs
-
11ICSSoft.FromERP/packages.config
-
6ICSSoft.Test/ICSSoft.Test.csproj
-
6ICSSoft.Test/ICSSoft.Test.csproj.user
-
4ICSSoft.Test/app.config
@ -0,0 +1,120 @@ |
|||||
|
using Newtonsoft.Json; |
||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.IO; |
||||
|
using System.Linq; |
||||
|
using System.Net.Http; |
||||
|
using System.Net; |
||||
|
using System.Reflection; |
||||
|
using System.Text; |
||||
|
using System.Threading.Tasks; |
||||
|
|
||||
|
namespace ICS.Common.Helpers |
||||
|
{ |
||||
|
public class HttpHelper |
||||
|
{ |
||||
|
#region Get请求
|
||||
|
///// <summary>
|
||||
|
///// 发送http Get请求
|
||||
|
///// </summary>
|
||||
|
///// <param name="url"></param>
|
||||
|
///// <returns></returns>
|
||||
|
//public static string GetRequest(string url)
|
||||
|
//{
|
||||
|
// HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
|
||||
|
// request.Method = "GET";
|
||||
|
// request.ContentType = "application/x-www-form-urlencoded";//链接类型
|
||||
|
// string result = GetResponseString(request.GetResponse() as HttpWebResponse);
|
||||
|
// return result;
|
||||
|
//}
|
||||
|
/// <summary>
|
||||
|
/// 从HttpWebResponse对象中提取响应的数据转换为字符串
|
||||
|
/// </summary>
|
||||
|
/// <param name="webresponse"></param>
|
||||
|
/// <returns></returns>
|
||||
|
public static string GetResponseString(HttpWebResponse webresponse) |
||||
|
{ |
||||
|
using (Stream s = webresponse.GetResponseStream()) |
||||
|
{ |
||||
|
StreamReader reader = new StreamReader(s, Encoding.UTF8); |
||||
|
return reader.ReadToEnd(); |
||||
|
} |
||||
|
} |
||||
|
#endregion
|
||||
|
|
||||
|
|
||||
|
public static bool PingTest(string ip) |
||||
|
{ |
||||
|
System.Net.NetworkInformation.Ping ping = new System.Net.NetworkInformation.Ping(); |
||||
|
|
||||
|
System.Net.NetworkInformation.PingReply pingStatus = |
||||
|
ping.Send(IPAddress.Parse(ip), 1000); |
||||
|
|
||||
|
if (pingStatus.Status == System.Net.NetworkInformation.IPStatus.Success) |
||||
|
{ |
||||
|
return true; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
return false; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public static bool WebRequestTest(string url) |
||||
|
{ |
||||
|
try |
||||
|
{ |
||||
|
System.Net.WebRequest myRequest = System.Net.WebRequest.Create(url); |
||||
|
System.Net.WebResponse myResponse = myRequest.GetResponse(); |
||||
|
} |
||||
|
catch (System.Net.WebException) |
||||
|
{ |
||||
|
return false; |
||||
|
} |
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// POST请求
|
||||
|
/// </summary>
|
||||
|
/// <param name="url">地址</param>
|
||||
|
/// <param name="requestJson">请求json</param>
|
||||
|
/// <param name="token">token</param>
|
||||
|
/// <returns></returns>
|
||||
|
public static async Task<T> HttpClientPost<T>(string url, string requestJson, string contentType = "application/json", string token = "") where T : new() |
||||
|
{ |
||||
|
|
||||
|
string result = string.Empty; |
||||
|
Uri postUrl = new Uri(url); |
||||
|
using (HttpContent httpContent = new StringContent(requestJson, System.Text.Encoding.UTF8, contentType)) |
||||
|
{ |
||||
|
//使用注入的httpclientfactory获取client
|
||||
|
using (var httpClient = new HttpClient()) |
||||
|
{ |
||||
|
//设置请求头
|
||||
|
//设置超时时间
|
||||
|
if (!string.IsNullOrEmpty(token)) |
||||
|
httpClient.DefaultRequestHeaders.Add("Authorization", "Bearer " + token); |
||||
|
httpClient.Timeout = new TimeSpan(0, 0, 60); |
||||
|
var response = httpClient.PostAsync(url, httpContent).Result; |
||||
|
|
||||
|
result = response.Content.ReadAsStringAsync().Result; |
||||
|
return JsonConvert.DeserializeObject<T>(result); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
public static async Task<T> HttpClientGet<T>(string url) where T : new() |
||||
|
{ |
||||
|
using (HttpClient httpClient = new HttpClient()) |
||||
|
{ |
||||
|
HttpResponseMessage res = httpClient.GetAsync(url).Result; |
||||
|
var t = res.Content.ReadAsStringAsync().Result; |
||||
|
return JsonConvert.DeserializeObject<T>(t); |
||||
|
|
||||
|
}; |
||||
|
|
||||
|
} |
||||
|
} |
||||
|
} |
@ -0,0 +1,324 @@ |
|||||
|
using ICS.Common.Helpers; |
||||
|
using Newtonsoft.Json; |
||||
|
using Quartz; |
||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Configuration; |
||||
|
using System.Data; |
||||
|
using System.IO; |
||||
|
using System.Linq; |
||||
|
using System.Reflection; |
||||
|
using System.Security.Policy; |
||||
|
using System.Text; |
||||
|
using System.Threading.Tasks; |
||||
|
using System.Xml.Linq; |
||||
|
|
||||
|
namespace ICSSoft.FromERP |
||||
|
{ |
||||
|
public class ICSAddStdWorkHourFromMES : IJob |
||||
|
{ |
||||
|
private static object key = new object(); |
||||
|
private static log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); |
||||
|
public void Execute(IJobExecutionContext context) |
||||
|
{ |
||||
|
try |
||||
|
{ |
||||
|
lock (key) |
||||
|
{ |
||||
|
log.Info("开始……………………………………………………………………"); |
||||
|
Execute(); |
||||
|
log.Info("结束……………………………………………………………………"); |
||||
|
} |
||||
|
} |
||||
|
catch (Exception ex) |
||||
|
{ |
||||
|
log.Error(ex.ToString()); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public async void Execute() |
||||
|
{ |
||||
|
try |
||||
|
{ |
||||
|
Configuration config = GetConfig(); |
||||
|
string url = config.ConnectionStrings.ConnectionStrings["APIAddStdWorkHour"].ConnectionString.ToString(); |
||||
|
log.Info("获取创建定额工时接口 " + url); |
||||
|
if (string.IsNullOrEmpty(url)) |
||||
|
{ |
||||
|
return; |
||||
|
} |
||||
|
string conStr = ICSHelper.GetConnectString(); |
||||
|
string Namespace = this.GetType().Namespace; |
||||
|
List<string> ErrorCode = new List<string>(); |
||||
|
|
||||
|
// 业务逻辑 从u9那边料品关联工时表 找到没有工时数据的料品 再向mes这边根据料号找到数据 去匹配条件 计算出工时 给u9
|
||||
|
// 二 分别抓取整机、本体部、驱动部未统计的料号 本体部、驱动部逆向去找型号
|
||||
|
// 准备请求接口的数据集合
|
||||
|
var AddList = new List<AddStdWorkHourItem>(); |
||||
|
#region 未统计的整机料号
|
||||
|
string sqls = @"select a.code,mf.Id as MFId,mfvb.ValueModel,mfvb.NominalDiameter,ISNULL(SpecialRequirement_ValveBodySpec,'') as SpecialRequirement from ERP.U9DB.dbo.CBO_ItemMaster a
|
||||
|
join (select ROW_NUMBER() over(partition by ManufacturingSerial order by Id desc) as MFIdFlag,Id,ItemModel,ManufacturingSerial,TenantId from IcsManufacturingHead ) mf |
||||
|
on mf.MFIdFlag = 1 and a.code = mf.ManufacturingSerial --and mf.TenantId = '' |
||||
|
join IcsMfValveBodySpec mfvb on mf.Id = mfvb.MFId |
||||
|
left join ERP.U9DB.dbo.CA_StdWorkingHours b |
||||
|
on a.Id = b.ItemMaster |
||||
|
LEFT OUTER JOIN ERP.U9DB.dbo.Base_Organization AS oo |
||||
|
ON oo.ID = a.Org |
||||
|
where oo.Code = '01' and b.id is null and a.code like 'KA%' and mfvb.ValueModel is not null";
|
||||
|
DataTable dt = ICSHelper.ExecuteTable(conStr, sqls); |
||||
|
|
||||
|
if (dt != null) |
||||
|
{ |
||||
|
log.Info("查询到整机待统计数量:" + dt.Rows.Count + "。"); |
||||
|
//准备整机条件
|
||||
|
string argsqls = @"select ItemModel,Type,NominalDiameter,Coefficient,ManHour,AdditiveManHour,ISNULL(SpecialRequirement,'') as SpecialRequirement
|
||||
|
from IcsProductionDurationStatistics |
||||
|
where Type = 0 --and TenantId = ''";
|
||||
|
DataTable argdt = ICSHelper.ExecuteTable(conStr, argsqls); |
||||
|
if (argdt != null) |
||||
|
{ |
||||
|
foreach (DataRow dr in dt.Rows) |
||||
|
{ |
||||
|
// 整机条件过滤 阀门型号、口径、特殊要求
|
||||
|
DataRow[] infoArgRow = argdt?.Select("ItemModel='" + dr["ValueModel"].ToString() |
||||
|
+ "' and SpecialRequirement = '" + dr["SpecialRequirement"].ToString() //特殊条件都为空 或者有特殊条件
|
||||
|
+ "' and NominalDiameter = '" + dr["NominalDiameter"].ToString() |
||||
|
+ "'"); |
||||
|
if (infoArgRow.Length > 0) |
||||
|
{ |
||||
|
var Manhour = infoArgRow[0]["ManHour"].ToDecimal(); //本体基础工时
|
||||
|
var AdditiveManHour = infoArgRow[0]["AdditiveManHour"].ToDecimal();//追加工时
|
||||
|
var Coefficient = infoArgRow[0]["Coefficient"].ToDecimal();//系数
|
||||
|
AddList.Add(new AddStdWorkHourItem() |
||||
|
{ |
||||
|
ORGCode = "01",//u9 Base_Organization表 的 code 字段 组织编码
|
||||
|
WorkHour = (Manhour + AdditiveManHour) * Coefficient, // 整机计算逻辑:(本体基础工时型号 + 追加工时) * 系数
|
||||
|
CreatedByCode = "", |
||||
|
DepartmentCode = "",//部门
|
||||
|
ItemCode = dr["code"].ToString() |
||||
|
}); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
//记录未匹配到条件 统计失败的料号
|
||||
|
ErrorCode.Add(dr["code"].ToString()); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
log.Info("整机待统计数量:" + dt.Rows.Count + "。但未查询到整机条件配置,已跳过生成。"); |
||||
|
} |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
log.Info("查询到整机待统计数量:0。"); |
||||
|
} |
||||
|
#endregion
|
||||
|
|
||||
|
#region 未统计的本体部
|
||||
|
string vbssqls = @"select b.MFId,a.code,mfvb.ValueModel,mfvb.NominalDiameter,ISNULL(SpecialRequirement_ValveBodySpec,'') as SpecialRequirement from ERP.U9DB.dbo.CBO_ItemMaster a
|
||||
|
join (select ROW_NUMBER() over(partition by PartItemCode order by MFId desc) as Flag,PartItemCode,MFId from ICSPartItem where PartItemName = '阀本体部') b -- and TenantId = '' |
||||
|
on a.code = b.PartItemCode and b.Flag = 1 |
||||
|
join IcsMfValveBodySpec mfvb on b.MFId = mfvb.MFId |
||||
|
left join ERP.U9DB.dbo.CA_StdWorkingHours c on a.Id = c.ItemMaster |
||||
|
LEFT OUTER JOIN ERP.U9DB.dbo.Base_Organization AS oo ON oo.ID = a.Org |
||||
|
where oo.Code = '01' and c.id is null and a.code like 'A2001%'";
|
||||
|
DataTable vbsdt = ICSHelper.ExecuteTable(conStr, vbssqls); |
||||
|
if (vbsdt != null) |
||||
|
{ |
||||
|
log.Info("查询到本体部待统计数量:" + vbsdt.Rows.Count + "。"); |
||||
|
//准备本体部条件 ItemModel型号 驱动部类型时此字段为驱动型号
|
||||
|
string vbsargsqls = @"select ItemModel,Type,NominalDiameter,Coefficient,ManHour,AdditiveManHour,ISNULL(SpecialRequirement,'') as SpecialRequirement
|
||||
|
from IcsProductionDurationStatistics |
||||
|
where Type = 1 --and TenantId = ''";
|
||||
|
DataTable vbsargdt = ICSHelper.ExecuteTable(conStr, vbsargsqls); |
||||
|
if (vbsargdt != null) |
||||
|
{ |
||||
|
foreach (DataRow dr in vbsdt.Rows) |
||||
|
{ |
||||
|
// 本体部条件过滤 阀门型号、口径、特殊条件
|
||||
|
DataRow[] infoVbsRow = vbsargdt?.Select("ItemModel='" + dr["ValueModel"].ToString() |
||||
|
+ "' and SpecialRequirement = '" + dr["SpecialRequirement"].ToString() //特殊条件都为空 或者有特殊条件
|
||||
|
+ "' and NominalDiameter = '" + dr["NominalDiameter"].ToString() |
||||
|
+ "'"); |
||||
|
if (infoVbsRow.Length > 0) |
||||
|
{ |
||||
|
var Manhour = infoVbsRow[0]["ManHour"].ToDecimal(); //本体基础工时
|
||||
|
var AdditiveManHour = infoVbsRow[0]["AdditiveManHour"].ToDecimal();//追加工时
|
||||
|
var Coefficient = infoVbsRow[0]["Coefficient"].ToDecimal();//系数
|
||||
|
AddList.Add(new AddStdWorkHourItem() |
||||
|
{ |
||||
|
ORGCode = "01",//u9 Base_Organization表 的 code 字段 组织编码
|
||||
|
WorkHour = (Manhour + AdditiveManHour) * Coefficient, // 本体部计算逻辑:(本体基础工时型号 + 追加工时) * 系数
|
||||
|
CreatedByCode = "", |
||||
|
DepartmentCode = "",//部门
|
||||
|
ItemCode = dr["code"].ToString() |
||||
|
}); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
//记录未匹配到条件 统计失败的料号
|
||||
|
ErrorCode.Add(dr["code"].ToString()); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
log.Info("本体部待统计数量:" + vbsdt.Rows.Count + "。但未查询到本体部条件配置,已跳过生成。"); |
||||
|
} |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
log.Info("查询到本体部待统计数量:0。"); |
||||
|
} |
||||
|
#endregion
|
||||
|
#region 未统计的驱动部
|
||||
|
string dssqls = @"select d.DriveModel,case when ISNULL(d.HandwheelMechanism,'NON') = 'NON' then 1 else 0 end as HandwheelMechanism,b.MFId,a.code
|
||||
|
from ERP.U9DB.dbo.CBO_ItemMaster a |
||||
|
join (select ROW_NUMBER() over(partition by PartItemCode order by MFId desc) as Flag,PartItemCode,MFId from ICSPartItem where PartItemName = '驱动部') b |
||||
|
on a.code = b.PartItemCode |
||||
|
join IcsMfDriverSpec d on b.MFId = d.MFId |
||||
|
left join ERP.U9DB.dbo.CA_StdWorkingHours c on a.Id = c.ItemMaster |
||||
|
LEFT OUTER JOIN ERP.U9DB.dbo.Base_Organization AS oo ON oo.ID = a.Org |
||||
|
where oo.Code = '01' and c.id is null and a.code like 'A2002%''";
|
||||
|
DataTable dsdt = ICSHelper.ExecuteTable(conStr, dssqls); |
||||
|
if (dsdt != null) |
||||
|
{ |
||||
|
log.Info("查询到驱动部待统计数量:" + dsdt.Rows.Count + "。"); |
||||
|
//准备驱动部条件 ItemModel型号 驱动部类型时此字段为驱动型号
|
||||
|
string dsArgsqls = @"select ItemModel,Type,Coefficient,ManHour,AdditiveManHour,HandwheelMechanism
|
||||
|
from IcsProductionDurationStatistics |
||||
|
where Type = 2 --and TenantId = ''";
|
||||
|
DataTable dsArgdt = ICSHelper.ExecuteTable(conStr, dsArgsqls); |
||||
|
if (dsArgdt != null) |
||||
|
{ |
||||
|
foreach (DataRow dr in vbsdt.Rows) |
||||
|
{ |
||||
|
// 驱动部条件过滤 驱动型号、是否有手轮机构
|
||||
|
DataRow[] infoDsArgRow = dsArgdt?.Select("ItemModel='" + dr["DriveModel"].ToString() |
||||
|
+ "' and HandwheelMechanism = '" + dr["HandwheelMechanism"].ToString() |
||||
|
+ "'"); |
||||
|
if (infoDsArgRow.Length > 0) |
||||
|
{ |
||||
|
var Manhour = infoDsArgRow[0]["ManHour"].ToDecimal(); //本体基础工时
|
||||
|
var AdditiveManHour = infoDsArgRow[0]["AdditiveManHour"].ToDecimal();//追加工时
|
||||
|
var Coefficient = infoDsArgRow[0]["Coefficient"].ToDecimal();//系数
|
||||
|
AddList.Add(new AddStdWorkHourItem() |
||||
|
{ |
||||
|
ORGCode = "01",//u9 Base_Organization表 的 code 字段 组织编码
|
||||
|
WorkHour = (Manhour + AdditiveManHour) * Coefficient, // 驱动部计算逻辑:(本体基础工时型号 + 追加工时) * 系数
|
||||
|
CreatedByCode = "", |
||||
|
DepartmentCode = "",//部门
|
||||
|
ItemCode = dr["code"].ToString() |
||||
|
}); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
//记录未匹配到条件 统计失败的料号
|
||||
|
ErrorCode.Add(dr["code"].ToString()); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
log.Info("驱动部待统计数量:" + dsdt.Rows.Count + "。但未查询到驱动部条件配置,已跳过生成。"); |
||||
|
} |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
log.Info("查询到驱动部待统计数量:0。"); |
||||
|
} |
||||
|
#endregion
|
||||
|
|
||||
|
if (ErrorCode.Any()) |
||||
|
{ |
||||
|
log.Info("未匹配到统计条件的料号:" + string.Join(",", ErrorCode) + "。"); |
||||
|
} |
||||
|
log.Info("创建定额工时Req:" + JsonConvert.SerializeObject(AddList)); |
||||
|
var response = await HttpHelper.HttpClientPost<AddStdWorkHourReq>(url, JsonConvert.SerializeObject(AddList)); |
||||
|
//返回成功后 用流水号填写 表头产品名称、产品编码、u9料号
|
||||
|
if (response != null) |
||||
|
{ |
||||
|
if (response.IsOK) |
||||
|
{ |
||||
|
log.Info("请求成功。" + response.Message); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
log.Info("请求失败。" + response.Message); |
||||
|
} |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
log.Info("未拿到响应,请求失败。"); |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
catch (Exception ex) |
||||
|
{ |
||||
|
log.Error(ex.ToString()); |
||||
|
} |
||||
|
} |
||||
|
public static Configuration GetConfig() |
||||
|
{ |
||||
|
Assembly assembly = Assembly.GetCallingAssembly(); |
||||
|
string path = string.Format("{0}.config", assembly.Location); |
||||
|
if (!File.Exists(path)) |
||||
|
{ |
||||
|
throw new FileNotFoundException(path + "路径下的文件未找到!"); |
||||
|
} |
||||
|
try |
||||
|
{ |
||||
|
ExeConfigurationFileMap configFile = new ExeConfigurationFileMap(); |
||||
|
configFile.ExeConfigFilename = path; |
||||
|
Configuration config = ConfigurationManager.OpenMappedExeConfiguration(configFile, ConfigurationUserLevel.None); |
||||
|
return config; |
||||
|
} |
||||
|
catch (Exception) |
||||
|
{ |
||||
|
throw; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
/// <summary>
|
||||
|
/// 创建定额工时接口入参
|
||||
|
/// </summary>
|
||||
|
public class AddStdWorkHourItem |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// 组织编码
|
||||
|
/// </summary>
|
||||
|
public string ORGCode { get; set; } |
||||
|
/// <summary>
|
||||
|
/// 料品编码
|
||||
|
/// </summary>
|
||||
|
public string ItemCode { get; set; } |
||||
|
/// <summary>
|
||||
|
/// 创建人编码
|
||||
|
/// </summary>
|
||||
|
public string CreatedByCode { get; set; } |
||||
|
/// <summary>
|
||||
|
/// 工时(单位:小时)
|
||||
|
/// </summary>
|
||||
|
public decimal WorkHour { get; set; } |
||||
|
/// <summary>
|
||||
|
/// 部门编码
|
||||
|
/// </summary>
|
||||
|
public string DepartmentCode { get; set; } |
||||
|
} |
||||
|
/// <summary>
|
||||
|
/// 响应
|
||||
|
/// </summary>
|
||||
|
public class AddStdWorkHourReq |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// true:成功;false:失败
|
||||
|
/// </summary>
|
||||
|
public bool IsOK { get; set; } |
||||
|
/// <summary>
|
||||
|
/// 消息
|
||||
|
/// </summary>
|
||||
|
public string Message { get; set; } |
||||
|
} |
||||
|
} |
@ -0,0 +1,143 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Linq; |
||||
|
using System.Reflection; |
||||
|
using System.Text; |
||||
|
using System.Threading.Tasks; |
||||
|
|
||||
|
namespace ICS.Common.DesignPattern |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// 单例模式
|
||||
|
/// </summary>
|
||||
|
public static class Singleton<T> where T : class, new() |
||||
|
{ |
||||
|
// 定义一个静态变量来保存类的实例
|
||||
|
private static T uniqueInstance; |
||||
|
// 定义一个标识确保线程同步
|
||||
|
private static object locker = null; |
||||
|
// 定义私有构造函数,使外界不能创建该类实例
|
||||
|
static Singleton() |
||||
|
{ |
||||
|
locker = new object(); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 定义公有方法提供一个全局访问点,同时你也可以定义公有属性来提供全局访问点
|
||||
|
/// </summary>
|
||||
|
/// <returns></returns>
|
||||
|
public static T GetInstance() |
||||
|
{ |
||||
|
// 当第一个线程运行到这里时,此时会对locker对象 "加锁",
|
||||
|
// 当第二个线程运行该方法时,首先检测到locker对象为"加锁"状态,该线程就会挂起等待第一个线程解锁
|
||||
|
// lock语句运行完之后(即线程运行完之后)会对该对象"解锁"
|
||||
|
// 双重锁定只需要一句判断就可以了
|
||||
|
if (uniqueInstance == null) |
||||
|
{ |
||||
|
lock (locker) |
||||
|
{ |
||||
|
// 如果类的实例不存在则创建,否则直接返回
|
||||
|
if (uniqueInstance == null) |
||||
|
{ |
||||
|
try |
||||
|
{ |
||||
|
// uniqueInstance = Activator.CreateInstance<T>();
|
||||
|
ConstructorInfo constructorInfo = null; |
||||
|
try |
||||
|
{ |
||||
|
constructorInfo = typeof(T).GetConstructor(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public, null, new Type[0], null); |
||||
|
} |
||||
|
catch (Exception ex) |
||||
|
{ |
||||
|
throw new InvalidOperationException(ex.Message, ex); |
||||
|
} |
||||
|
|
||||
|
if (constructorInfo == null || constructorInfo.IsAssembly) |
||||
|
{ |
||||
|
throw new InvalidOperationException($"在'{typeof(T).Name}'里面没有找到private或者protected的构造函数。"); |
||||
|
} |
||||
|
|
||||
|
uniqueInstance = (T)constructorInfo.Invoke(null); |
||||
|
} |
||||
|
catch (Exception) |
||||
|
{ |
||||
|
|
||||
|
throw; |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
return uniqueInstance; |
||||
|
} |
||||
|
public static T GetInstance(object[] para) |
||||
|
{ |
||||
|
// 当第一个线程运行到这里时,此时会对locker对象 "加锁",
|
||||
|
// 当第二个线程运行该方法时,首先检测到locker对象为"加锁"状态,该线程就会挂起等待第一个线程解锁
|
||||
|
// lock语句运行完之后(即线程运行完之后)会对该对象"解锁"
|
||||
|
// 双重锁定只需要一句判断就可以了
|
||||
|
if (uniqueInstance == null) |
||||
|
{ |
||||
|
lock (locker) |
||||
|
{ |
||||
|
// 如果类的实例不存在则创建,否则直接返回
|
||||
|
if (uniqueInstance == null) |
||||
|
{ |
||||
|
try |
||||
|
{ |
||||
|
// uniqueInstance = Activator.CreateInstance<T>();
|
||||
|
ConstructorInfo constructorInfo = null; |
||||
|
try |
||||
|
{ |
||||
|
constructorInfo = typeof(T).GetConstructor(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public, null, new Type[1] { para[0].GetType() }, null); |
||||
|
} |
||||
|
catch (Exception ex) |
||||
|
{ |
||||
|
throw new InvalidOperationException(ex.Message, ex); |
||||
|
} |
||||
|
|
||||
|
if (constructorInfo == null || constructorInfo.IsAssembly) |
||||
|
{ |
||||
|
throw new InvalidOperationException($"在'{typeof(T).Name}'里面没有找到private或者protected的构造函数。"); |
||||
|
} |
||||
|
|
||||
|
uniqueInstance = (T)constructorInfo.Invoke(para); |
||||
|
} |
||||
|
catch (Exception) |
||||
|
{ |
||||
|
|
||||
|
throw; |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
return uniqueInstance; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
///
|
||||
|
/// </summary>
|
||||
|
public sealed class Singleton4<T> where T : class,new () |
||||
|
{ |
||||
|
private static readonly Singleton4<T> instance = new Singleton4<T>(); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 显式的静态构造函数用来告诉C#编译器在其内容实例化之前不要标记其类型
|
||||
|
/// </summary>
|
||||
|
static Singleton4() { } |
||||
|
|
||||
|
private Singleton4() { } |
||||
|
|
||||
|
public static Singleton4<T> Instance |
||||
|
{ |
||||
|
get |
||||
|
{ |
||||
|
return instance; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
@ -0,0 +1,11 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<packages> |
||||
|
<package id="log4net" version="2.0.17" targetFramework="net48" /> |
||||
|
<package id="System.IO" version="4.3.0" targetFramework="net48" /> |
||||
|
<package id="System.Net.Http" version="4.3.4" targetFramework="net48" /> |
||||
|
<package id="System.Runtime" version="4.3.0" targetFramework="net48" /> |
||||
|
<package id="System.Security.Cryptography.Algorithms" version="4.3.0" targetFramework="net48" /> |
||||
|
<package id="System.Security.Cryptography.Encoding" version="4.3.0" targetFramework="net48" /> |
||||
|
<package id="System.Security.Cryptography.Primitives" version="4.3.0" targetFramework="net48" /> |
||||
|
<package id="System.Security.Cryptography.X509Certificates" version="4.3.0" targetFramework="net48" /> |
||||
|
</packages> |
@ -0,0 +1,6 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> |
||||
|
<PropertyGroup> |
||||
|
<ProjectView>ProjectFiles</ProjectView> |
||||
|
</PropertyGroup> |
||||
|
</Project> |
Write
Preview
Loading…
Cancel
Save
Reference in new issue