在工作过程中,我们总会碰到很多小型的功能点需要完成,以LZ自己的工作情况来举例,其中最频繁的是俩点 1、控制台项目 2、web界面(纯前台)
我们首先来谈控制台项目的工作内容,在没有使用postMan之前,工作中使用大量的接口调用,在项目准备阶段,首先要对接口的使用进行一个描述,在使用WebService和Wcf为主的服务接口为主的公司,使用Vs直接 <新建控制吧><添加服务引用>一套可视化的操作即可按接口通过代理类的方法进行引用,实在是c#开发的乐趣所在。 废话不多说,现在主要说说工作中常用的功能点 1、测试服务接口 2、编写windows服务
控制台项目完成此功能很简单,本文章主要突出的是一些常用的方法。 在编写类项目的过程中,主要会用到三个类库 1.Newtonsoftjson(json序列化) 2.log4net(日志记录) 3.NUint(单元测试)
业务上无非就是调用接口测试,如果成功Pass,如果失败记录日志。 单元测试的目的主要是为了,批量使用接口,测试接口的并发和其他操作所用
windows服务的使用场景在我的工作中主要结合任务调度来来做,同时配合一些其他的技术,像是队列,缓存等 例子: 1、每隔10秒同步一次A数据库数据(SqlServer)至B数据库(Oracle),表名称,字段名称均不一样 2、每天凌晨2点跑一项或多项任务,成功失败均记录日志+推送管理员(手机短信、邮件、内部服务平台)
大体上都是结合任务调度来做的,进行任务调试的库一般选用的是Quartz.Net,console服务转Windows服务用的是topshelf,日志使用Log4net 通过这三个组件就能够满足我的一般需求,其他的功能点按要求要引用不同的类库。
新建一个console 项目,运行环境选择.Net Framework 4.5
新建解决方案
建立三个类库 Common 基础层 Models 实体层 ScheduleTasks 任务具体任务
结构图.png
首先引用Nuget包,不同的层引用不同的Nuget,再次简单说明 Common 基础层
log4net、quartz.net
Models 实体层
Sqlsugar
Schedules
待定
进行不同的模块封装
log4Net不需要做太多的封装,提供一个初始化,一个日志接口获取方法即可
public class LogFactory
{
static LogFactory()
{
string path = AppDomain.CurrentDomain.BaseDirectory + @"/log4net.config";
FileInfo configFile=new FileInfo(path);
log4net.Config.XmlConfigurator.Configure();
}
public static ILog GetLogger(string name)
{
return LogManager.GetLogger(name);
}
public static ILog GetLogger(Type type)
{
return LogManager.GetLogger(type);
}
}
最简单的config日志配置
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/>
</configSections>
<log4net>
<!-- 控制台前台显示日志 -->
<appender name="Console" type="log4net.Appender.ColoredConsoleAppender">
<mapping>
<level value="DEBUG" />
<foreColor value="White" />
</mapping>
<mapping>
<level value="INFO" />
<foreColor value="Blue" />
</mapping>
<mapping>
<level value="WARN" />
<foreColor value="Yellow" />
</mapping>
<mapping>
<level value="ERROR" />
<foreColor value="Red, HighIntensity" />
</mapping>
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="时间:%date 级别:%-5level 日志记录器:%logger%n内容:%message%n%n" />
</layout>
<filter type="log4net.Filter.LevelRangeFilter">
<param name="LevelMin" value="Debug" />
<param name="LevelMax" value="Fatal" />
</filter>
</appender>
<appender name="LogByDate" type="log4net.Appender.RollingFileAppender">
<!--日志路径-->
<param name= "File" value= "Log//"/>
<!--记录日志写入文件时,不锁定文本文件,防止多线程时不能写Log,官方说线程非安全-->
<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
<!--是否是向文件中追加日志-->
<param name= "AppendToFile" value= "true"/>
<!--最多产生的日志文件数,超过则只保留最新的n个。设定值value="-1"为不限文件数-->
<param name= "MaxSizeRollBackups" value= "-1"/>
<param name="MaximumFileSize" value="10MB" />
<!--日志文件名是否是固定不变的-->
<param name= "StaticLogFileName" value= "false"/>
<!--固定后缀-->
<PreserveLogFileNameExtension value="true" />
<param name="DatePattern" value="yyyyMMdd".log"" />
<!--按照何种方式产生多个日志文件(日期[Date],文件大小[Size],混合[Composite])-->
<param name= "RollingStyle" value= "Composite"/>
<layout type="log4net.Layout.PatternLayout">
<param name="ConversionPattern" value="%n时间:%d [%t] %n级别:%-5p %n位置:[%thread] (%file:%line) %n消息描述:%message%n异常:%exception%n%n " />
</layout>
</appender>
<!--root节点的作用是所有其它logger都默认继承它。-->
<root>
<!--配置日志的级别,低于此级别的就不写到日志里面去-->
<!--(高) OFF > FATAL > ERROR > WARN > INFO > DEBUG > ALL (低) -->
<level value="ALL" />
<!--启用日志输入到控制台-->
<appender-ref ref="Console"/>
<appender-ref ref="LogByDate"/>
</root>
</log4net>
</configuration>
至此log4net的工作完成
image.png
版本随便你自己使用
在程序的编码过程中经常会用到json的序列化和么序列化 编写一个简单的help class
/// <summary>
/// Json帮助类
/// </summary>
public class JsonHelper
{
/// <summary>
/// 将对象序列化为JSON格式
/// </summary>
/// <param name="o">对象</param>
/// <returns>json字符串</returns>
public static string SerializeObject(object o)
{
string json = JsonConvert.SerializeObject(o);
return json;
}
/// <summary>
/// 解析JSON字符串生成对象实体
/// </summary>
/// <typeparam name="T">对象类型</typeparam>
/// <param name="json">json字符串(eg.{"ID":"112","Name":"石子儿"})</param>
/// <returns>对象实体</returns>
public static T DeserializeJsonToObject<T>(string json) where T : class
{
JsonSerializer serializer = new JsonSerializer();
StringReader sr = new StringReader(json);
object o = serializer.Deserialize(new JsonTextReader(sr), typeof(T));
T t = o as T;
return t;
}
/// <summary>
/// 解析JSON数组生成对象实体集合
/// </summary>
/// <typeparam name="T">对象类型</typeparam>
/// <param name="json">json数组字符串(eg.[{"ID":"112","Name":"石子儿"}])</param>
/// <returns>对象实体集合</returns>
public static List<T> DeserializeJsonToList<T>(string json) where T : class
{
JsonSerializer serializer = new JsonSerializer();
StringReader sr = new StringReader(json);
object o = serializer.Deserialize(new JsonTextReader(sr), typeof(List<T>));
List<T> list = o as List<T>;
return list;
}
/// <summary>
/// 反序列化JSON到给定的匿名对象.
/// </summary>
/// <typeparam name="T">匿名对象类型</typeparam>
/// <param name="json">json字符串</param>
/// <param name="anonymousTypeObject">匿名对象</param>
/// <returns>匿名对象</returns>
public static T DeserializeAnonymousType<T>(string json, T anonymousTypeObject)
{
T t = JsonConvert.DeserializeAnonymousType(json, anonymousTypeObject);
return t;
}
}