在工作過程中穆端,我們總會(huì)碰到很多小型的功能點(diǎn)需要完成,以LZ自己的工作情況來舉例仿便,其中最頻繁的是倆點(diǎn)
1体啰、控制臺項(xiàng)目
2、web界面(純前臺)
控制臺項(xiàng)目
我們首先來談控制臺項(xiàng)目的工作內(nèi)容探越,在沒有使用postMan地址詳見之前狡赐,工作中使用大量的接口調(diào)用,在項(xiàng)目準(zhǔn)備階段钦幔,首先要對接口的使用進(jìn)行一個(gè)描述枕屉,在使用WebService和Wcf為主的服務(wù)接口為主的公司,使用Vs直接 <新建控制吧><添加服務(wù)引用>一套可視化的操作即可按接口通過代理類的方法進(jìn)行引用鲤氢,實(shí)在是c#開發(fā)的樂趣所在搀擂。
廢話不多說西潘,現(xiàn)在主要說說工作中常用的功能點(diǎn)
1、測試服務(wù)接口
2哨颂、編寫windows服務(wù)
服務(wù)接口
控制臺項(xiàng)目完成此功能很簡單喷市,本文章主要突出的是一些常用的方法。
在編寫類項(xiàng)目的過程中威恼,主要會(huì)用到三個(gè)類庫
1.Newtonsoftjson(json序列化)
2.log4net(日志記錄)
3.NUint(單元測試)
業(yè)務(wù)上無非就是調(diào)用接口測試品姓,如果成功Pass,如果失敗記錄日志箫措。
單元測試的目的主要是為了腹备,批量使用接口,測試接口的并發(fā)和其他操作所用
Windows服務(wù)
windows服務(wù)的使用場景在我的工作中主要結(jié)合任務(wù)調(diào)度來來做斤蔓,同時(shí)配合一些其他的技術(shù)植酥,像是隊(duì)列,緩存等
例子:
1弦牡、每隔10秒同步一次A數(shù)據(jù)庫數(shù)據(jù)(SqlServer)至B數(shù)據(jù)庫(Oracle),表名稱友驮,字段名稱均不一樣
2、每天凌晨2點(diǎn)跑一項(xiàng)或多項(xiàng)任務(wù)驾锰,成功失敗均記錄日志+推送管理員(手機(jī)短信卸留、郵件、內(nèi)部服務(wù)平臺)
大體上都是結(jié)合任務(wù)調(diào)度來做的稻据,進(jìn)行任務(wù)調(diào)試的庫一般選用的是Quartz.Net,console服務(wù)轉(zhuǎn)Windows服務(wù)用的是topshelf,日志使用Log4net
通過這三個(gè)組件就能夠滿足我的一般需求艾猜,其他的功能點(diǎn)按要求要引用不同的類庫。
簡單項(xiàng)目搭建
項(xiàng)目搭建1.0
新建一個(gè)console 項(xiàng)目捻悯,運(yùn)行環(huán)境選擇.Net Framework 4.5
新建解決方案
建立三個(gè)類庫
Common 基礎(chǔ)層
Models 實(shí)體層
ScheduleTasks 任務(wù)具體任務(wù)
首先引用Nuget包,不同的層引用不同的Nuget,再次簡單說明
Common 基礎(chǔ)層
log4net甩骏、quartz.net
Models 實(shí)體層
Sqlsugar
Schedules
待定
進(jìn)行不同的模塊封裝
log4net 的引用和封裝
log4Net不需要做太多的封裝族吻,提供一個(gè)初始化,一個(gè)日志接口獲取方法即可
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="時(shí)間:%date 級別:%-5level 日志記錄器:%logger%n內(nèi)容:%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//"/>
<!--記錄日志寫入文件時(shí),不鎖定文本文件外厂,防止多線程時(shí)不能寫Log,官方說線程非安全-->
<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
<!--是否是向文件中追加日志-->
<param name= "AppendToFile" value= "true"/>
<!--最多產(chǎn)生的日志文件數(shù)泽台,超過則只保留最新的n個(gè)莽龟。設(shè)定值value="-1"為不限文件數(shù)-->
<param name= "MaxSizeRollBackups" value= "-1"/>
<param name="MaximumFileSize" value="10MB" />
<!--日志文件名是否是固定不變的-->
<param name= "StaticLogFileName" value= "false"/>
<!--固定后綴-->
<PreserveLogFileNameExtension value="true" />
<param name="DatePattern" value="yyyyMMdd".log"" />
<!--按照何種方式產(chǎn)生多個(gè)日志文件(日期[Date],文件大小[Size],混合[Composite])-->
<param name= "RollingStyle" value= "Composite"/>
<layout type="log4net.Layout.PatternLayout">
<param name="ConversionPattern" value="%n時(shí)間:%d [%t] %n級別:%-5p %n位置:[%thread] (%file:%line) %n消息描述:%message%n異常:%exception%n%n " />
</layout>
</appender>
<!--root節(jié)點(diǎn)的作用是所有其它logger都默認(rèn)繼承它岁经。-->
<root>
<!--配置日志的級別,低于此級別的就不寫到日志里面去-->
<!--(高) OFF > FATAL > ERROR > WARN > INFO > DEBUG > ALL (低) -->
<level value="ALL" />
<!--啟用日志輸入到控制臺-->
<appender-ref ref="Console"/>
<appender-ref ref="LogByDate"/>
</root>
</log4net>
</configuration>
至此log4net的工作完成
Newtonsoftjson
版本隨便你自己使用
在程序的編碼過程中經(jīng)常會(huì)用到j(luò)son的序列化和么序列化
編寫一個(gè)簡單的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字符串生成對象實(shí)體
/// </summary>
/// <typeparam name="T">對象類型</typeparam>
/// <param name="json">json字符串(eg.{"ID":"112","Name":"石子兒"})</param>
/// <returns>對象實(shí)體</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數(shù)組生成對象實(shí)體集合
/// </summary>
/// <typeparam name="T">對象類型</typeparam>
/// <param name="json">json數(shù)組字符串(eg.[{"ID":"112","Name":"石子兒"}])</param>
/// <returns>對象實(shí)體集合</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;
}
}