在工作过程中,我们总会碰到很多小型的功能点需要完成,以LZ自己的工作情况来举例,其中最频繁的是俩点
1、控制台项目
2、web界面(纯前台)
控制台项目
我们首先来谈控制台项目的工作内容,在没有使用postMan地址详见之前,工作中使用大量的接口调用,在项目准备阶段,首先要对接口的使用进行一个描述,在使用WebService和Wcf为主的服务接口为主的公司,使用Vs直接 <新建控制吧><添加服务引用>一套可视化的操作即可按接口通过代理类的方法进行引用,实在是c#开发的乐趣所在。
废话不多说,现在主要说说工作中常用的功能点
1、测试服务接口
2、编写windows服务
服务接口
控制台项目完成此功能很简单,本文章主要突出的是一些常用的方法。
在编写类项目的过程中,主要会用到三个类库
1.Newtonsoftjson(json序列化)
2.log4net(日志记录)
3.NUint(单元测试)
业务上无非就是调用接口测试,如果成功Pass,如果失败记录日志。
单元测试的目的主要是为了,批量使用接口,测试接口的并发和其他操作所用
Windows服务
windows服务的使用场景在我的工作中主要结合任务调度来来做,同时配合一些其他的技术,像是队列,缓存等
例子:
1、每隔10秒同步一次A数据库数据(SqlServer)至B数据库(Oracle),表名称,字段名称均不一样
2、每天凌晨2点跑一项或多项任务,成功失败均记录日志+推送管理员(手机短信、邮件、内部服务平台)
大体上都是结合任务调度来做的,进行任务调试的库一般选用的是Quartz.Net,console服务转Windows服务用的是topshelf,日志使用Log4net
通过这三个组件就能够满足我的一般需求,其他的功能点按要求要引用不同的类库。
简单项目搭建
项目搭建1.0
新建一个console 项目,运行环境选择.Net Framework 4.5
新建解决方案
建立三个类库
Common 基础层
Models 实体层
ScheduleTasks 任务具体任务
首先引用Nuget包,不同的层引用不同的Nuget,再次简单说明
Common 基础层
log4net、quartz.net
Models 实体层
Sqlsugar
Schedules
待定
进行不同的模块封装
log4net 的引用和封装
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的工作完成
Newtonsoftjson
版本随便你自己使用
在程序的编码过程中经常会用到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;
}
}