.net 6及以上版本 普通控制台程序 初始化项目介绍(非WebAPI)
最近做了一本地exe程序, 需要简单初始化一个.net core 10 的 Console 项目. 包括读取本地配置文件 appsettings.json,以及使用日志 啥的.
本来最开始使用 Nlog作为日志记录的 ( 之前 ZR.Admin 里面 就是用的 Nlog ) ,结果项目开发完,说需要 对接 之前一个项目的 Elasticsearch(ES) ,头大,也不太方便调试ES,所以就抄原来的项目,直接使用原来项目的配置, 改为使用Log4Net了.
控制台Console项目 ,首先肯定是要记录日志, 读取配置文件啥的.然后操作数据库,使用SqlSugar,经典的三层模式(Model,DAL,BLL)调用就行了.
这里配置文件贴一下.
1.配置文件 Log4net.config
Log4net.config连接ES日志
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<!-- This section contains the log4net configuration settings -->
<log4net>
<appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender">
<layout type="log4net.Layout.PatternLayout" value="%date [%thread] | %-5level | %message%newline" />
</appender>
<appender name="FileAppender" type="log4net.Appender.FileAppender">
<file value="log-file.log" />
<appendToFile value="true" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] | %-5level| %message%newline" />
</layout>
</appender>
<appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender">
<file value="logfile/" />
<appendToFile value="true" />
<rollingStyle value="Composite" />
<staticLogFileName value="false" />
<datePattern value="yyyyMMdd'.log'" />
<maxSizeRollBackups value="10" />
<maximumFileSize value="1MB" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] | %-5level | %message%newline" />
</layout>
</appender>
<appender name="ElasticSearchAppender" type="log4net.ElasticSearchAppender.DotNetCore.ElasticSearchAppender, log4net.ElasticSearchAppender.DotNetCore">
<Server>${"ES服务器地址:xxx.xxx.xxx.xxx"}</Server>
<Port>9200</Port>
<IndexName>${"ES服务器上搭建好的日志模块名称:xxxLog"}_%{+yyyy-MM-dd}</IndexName>
</appender>
<!-- Setup the root category, add the appenders and set the default level -->
<root>
<level value="ALL" />
<appender-ref ref="ConsoleAppender" />
<appender-ref ref="FileAppender" />
<appender-ref ref="RollingLogFileAppender" />
<!--<appender-ref ref="ElasticSearchAppender" /> -->
</root>
</log4net>
</configuration>
2.配置文件 appsettings.json
简单的任务配置以及数据库配置
{
"TaskConfig": {
"MaxThreadCount": 50,
"ThreadSleepTime": 5,
"GroupNum": 5
},
"ConnectionStrings": {
"conn_db_type": "3", // 数据库类型 SqlServer = 1,oracle =3,PostgreSQL=4
"conn_db_main": "xxx"; // 数据库链接配置
}
}
备注: 建议使用全局静态类 存储 配置项.
3.通用日志类 Log4NetHelper.cs
Log4NetHelper.cs 能用
using log4net;
using log4net.Config;
using log4net.Repository;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace HelpCommon
{
public class Log4NetHelper
{
private static string repositoryName = string.Empty;
private static string logName = "xxxLog";
private static log4net.ILog log = log4net.LogManager.GetLogger(logName);
public static void Init()
{
ILoggerRepository repository = LogManager.CreateRepository("xxxLog");
XmlConfigurator.Configure(repository, new FileInfo("Log4net.config"));
repositoryName = repository.Name;
log = LogManager.GetLogger(repository.Name, logName);
}
public static void ConsoleInfo(string msg)
{
Info(msg);
Console.WriteLine(msg);
}
public static void Debug(string message)
{
log4net.ILog log = log4net.LogManager.GetLogger(logName);
if (log.IsDebugEnabled)
{
log.Debug(message);
}
log = null;
}
public static void Debug(string message, Exception ex)
{
if (log.IsDebugEnabled)
{
log.Debug(message, ex);
}
}
public static void Error(string message)
{
if (log.IsErrorEnabled)
{
log.Error(message);
}
}
public static void Error(string message, Exception ex)
{
if (log.IsErrorEnabled)
{
log.Error(message, ex);
}
}
public static void Fatal(string message)
{
if (log.IsFatalEnabled)
{
log.Fatal(message);
}
}
public static void Fatal(string message, Exception ex)
{
if (log.IsFatalEnabled)
{
log.Fatal(message, ex);
}
}
public static void Info(string message)
{
if (log.IsInfoEnabled)
{
log.Info(message);
}
}
public static void Info(string message, Exception ex)
{
if (log.IsInfoEnabled)
{
log.Info(message, ex);
}
}
public static void Warn(string message)
{
if (log.IsWarnEnabled)
{
log.Warn(message);
}
}
public static void Warn(string message, Exception ex)
{
if (log.IsWarnEnabled)
{
log.Warn(message, ex);
}
}
}
}
需要说明的是, 有时候记录日志(写文件),也要同时输出在控制台(方便观察).所以加了个 Log4NetHelper. ConsoleInfo 方法.
4.全局配置类 GlobalSetting.cs
GlobalSetting 全局配置类
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Primitives;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace HelpCommon
{
public static class GlobalSetting
{
private static IConfigurationRoot config = null;
private static int _dbType;
public static int DbType
{
get
{
return _dbType;
}
}
private static string _dbConnStr;
public static string DbConnStr
{
get
{
return _dbConnStr;
}
}
public static DateTime LastDbTime { get; set; }
public static void Init()
{
var configuration = new ConfigurationBuilder().AddJsonFile("appsettings.json", optional: true, reloadOnChange: true);
config = configuration.Build();
// _maxCheckTime = GetSettingByInt("MaxCheckTime");
// IChangeToken changeToken = config.GetReloadToken();
}
/// <summary>
/// 初始化数据库配置
/// </summary>
public static void InitDB()
{
_dbConnStr = GetSetting("ConnectionStrings:conn_db_main");
_dbType = GetSettingByInt("ConnectionStrings:conn_db_type");
}
/// <summary>
/// 多个层级用英文:分割,例如: Logging:LogLevel:Default
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public static string GetSetting(string key)
{
try
{
var obj = config[key];
if (!string.IsNullOrEmpty(obj))
{
return obj;
}
return "";
}
catch
{
return "";
}
}
/// <summary>
/// 多个层级用英文:分割,例如: Logging:LogLevel:Default
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public static int GetSettingByInt(string key)
{
var obj = config[key];
if (int.TryParse(obj, out int p))
{
return p;
}
else
{
Console.WriteLine($"读取配置节[{key}]点错误");
// 没有对应的值,返回-1
return -1;
}
}
}
}
5.程序Main方法初始化
Main方法入口 初始化日志,配置
static void Main(string[] args)
{
Log4NetHelper.Init();
Log4NetHelper.ConsoleInfo("程序结束运行...");
InitConfig();
//这里写业务逻辑
Log4NetHelper.ConsoleInfo("程序结束运行...");
Console.WriteLine("程序终止运行");
Console.ReadLine();
}
static bool InitConfig()
{
try
{
Log4NetHelper.Info("加载配置文件并读取配置: ①数据库配置,②机器配置,③任务配置");
GlobalSetting.Init();
GlobalSetting.InitDB();
// GlobalSetting.InitTaskConfig(); 读取配置文件参数
// 检测一下数据库配置
if (GlobalSetting.DbConnStr.indexOf("xxx.xxx.xxx.xxx") > 0)
{
Console.Write("注意:当前数据库连接为 ");
Console.BackgroundColor = ConsoleColor.White;
Console.ForegroundColor = ConsoleColor.Red;
Console.Write(" [测试库] xxx.xxx.xxx.xxx ");
Console.BackgroundColor = ConsoleColor.Black;
Console.ForegroundColor = ConsoleColor.White;
Console.WriteLine(" ,按回车继续...");
Console.ReadLine();
}
Log4NetHelper.Info($"①数据库配置: 数据库类型:{GlobalSetting.DbType}");
//Log4NetHelper.Info($"②机器配置:" + JsonConvert.SerializeObject(GlobalSetting.MachineConfig));
//Log4NetHelper.Info($"③任务配置:" + JsonConvert.SerializeObject(GlobalSetting.TaskConfig));
// 更新数据库,注册配置 (回写到数据库)
//ConfigManagerBLL.SaveMachineConfig();
//ConfigManagerBLL.SaveTaskConfig();
// 检查数据库表里面配置的其他表或者参数, 如果没有配置, 需要提醒一下
string sjcMsf = string.Empty; ;
var checkAllowRun = ConfigManagerBLL.CheckConfigStartTime(ref sjcMsf);
while (!checkAllowRun)
{
Console.WriteLine("请检查 配置表 esb_task_config,设置 主机 取数的 开始时间戳和结束时间戳.....");
Thread.Sleep(5000);
checkAllowRun = ConfigManagerBLL.CheckConfigStartTime(ref sjcMsf);
}
Log4NetHelper.ConsoleInfo(sjcMsf);
return true;
}
catch (Exception ex)
{
Log4NetHelper.Error("初始化读取appsettings.json配置异常", ex);
return false;
}
}
5.解决方案项目结构
项目结构一目了然,经典的三层结构. HelpCommon 基本都是常用的类,不过多赘述.
需要说明的是 Lib目录 ,一般是放置 第三方DLL库之类的. 这里放几个文件说明,便于了解项目.(等时间一长,很多就都忘啦)

6.分页入参,出参通用类
EsbModel 下面有2个分页的实体类,一种是泛型的(返回值),另一个是分页入参(方法传参用)
泛型分页PagedInfo
/// <summary>
/// 分页参数
/// </summary>
public class PagedInfo<T>
{
/// <summary>
/// 每页行数
/// </summary>
public int PageSize { get; set; } = 10;
/// <summary>
/// 当前页
/// </summary>
public int PageIndex { get; set; } = 1;
/// <summary>
/// 总记录数
/// </summary>
public int TotalNum { get; set; }
/// <summary>
/// 总页数
/// </summary>
public int TotalPage
{
get
{
if (TotalNum > 0)
{
return TotalNum % this.PageSize == 0 ? TotalNum / this.PageSize : TotalNum / this.PageSize + 1;
}
else
{
return 0;
}
}
set { }
}
public List<T> Result { get; set; }
public Dictionary<string, object> Extra { get; set; } = new Dictionary<string, object>();
public PagedInfo()
{
}
}
分页方法入参传参 PagerInfo
public class PagerInfo
{
/// <summary>
/// 当前页码
/// </summary>
public int PageNum { get; set; }
public int PageSize { get; set; }
/// <summary>
/// 总记录数
/// </summary>
public int TotalNum { get; set; }
/// <summary>
/// 总页码
/// </summary>
/// <summary>
/// 总页数
/// </summary>
public int TotalPage
{
get
{
return TotalNum > 0 ? TotalNum % PageSize == 0 ? TotalNum / PageSize : TotalNum / PageSize + 1 : 0;
}
}
/// <summary>
/// 排序字段
/// </summary>
public string Sort { get; set; } = string.Empty;
/// <summary>
/// 排序类型,前端传入的是"ascending","descending"
/// </summary>
public string SortType { get; set; } = string.Empty;
public PagerInfo()
{
PageNum = 1;
PageSize = 20;
}
public PagerInfo(int page = 1, int pageSize = 20)
{
PageNum = page;
PageSize = pageSize;
}
}
7. 数据库操作 SqlSugarHelper
SqlSugarHelper 数据库操作
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Text;
using Newtonsoft.Json;
using System.Collections;
using System.Threading.Tasks;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data;
namespace HelpCommon
{
public static class SqlSugarHelper
{
public static string _connStr;
public static string connStr
{
get
{
if (string.IsNullOrEmpty(_connStr))
{
_connStr = GlobalSetting.DbConnStr;
}
return _connStr;
}
}
public static SqlSugarScope _db = null;
public static SqlSugarScope db
{
get
{
if (_db == null)
{
_db = new SqlSugarScope(new SqlSugar.ConnectionConfig()
{
ConnectionString = connStr,
DbType = SqlSugar.DbType.Oracle,
IsAutoCloseConnection = true,
// 需要查看运行时的sql,打开下面的注释
//AopEvents = new AopEvents
//{
// OnLogExecuting = (sql, p) =>
// {
// Parallel.For(0, 1, e =>
// {
// string sqlStr = GetParas(p) + "【SQL语句】:" + sql;
// Console.ForegroundColor = ConsoleColor.Green;
// Console.WriteLine(sqlStr);
// Console.ForegroundColor = ConsoleColor.White;
// });
// }
//},
}); ;
}
return _db;
}
}
private static string GetParas(SugarParameter[] pars)
{
string key = "【SQL参数】:";
foreach (var param in pars)
{
key += $"{param.ParameterName}:{param.Value}\n";
}
return key;
}
/*
批量新增/修改 使用: db.Storageable<T>(List<T>list).ExecuteCommand();
sql->List<T> 使用: db.Ado.SqlQuery<T>(sql, parms);
*/
public static DataTable GetDataTable(string sql, object parms = null)
{
return db.Ado.GetDataTable(sql, parms);
}
public static int ExecuteNonQuery(string sql, object parms = null)
{
return db.Ado.ExecuteCommand(sql, parms);
}
public static object GetScalar(string sql, object parms = null)
{
return db.Ado.GetScalar(sql, parms);
}
public static DateTime GetDbTime()
{
return Convert.ToDateTime(db.Ado.GetScalar("select sysdate from dual"));
}
public static DateTime GetDbTimeStemp()
{
var obj = db.Ado.GetScalar("select to_char(SYSTIMESTAMP,'YYYY-MM-DD HH24:MI:SS.ff6') from dual");
return TimeHelper.StrToSjc(obj.ToString());
}
}
}
需要说明的是 批量保存 和 实体类查询 方法
批量新增/修改 使用: db.Storageable<T>(List<T>list).ExecuteCommand();
sql -> List<T> 使用: db.Ado.SqlQuery<T>(sql, parms);
本文来自博客园,作者:兴想事成,转载请注明原文链接:https://www.cnblogs.com/mjxxsc/p/19376439

浙公网安备 33010602011771号