泛型静态类 & function 作为参数
- /// <summary>
- ///
- /// </summary>
- /// <typeparam name="OD">original datas type:get from proxy api</typeparam>
- /// <typeparam name="SD">save datas type</typeparam>
- public static class ReportOperation<OD,SD> where OD : class where SD : class
- {
- static int _syncCallApiMaxNum= ConfigHelper.SyncCallApiMaxNum;
- static int _MaxSaveDataNum = ConfigHelper.MaxSaveDataNum;
- static string OriginalDatasType = typeof(OD).FullName;
- static string SaveDatasType = typeof(SD).FullName;
- private static bool TaskSplitForSave(List<ReportSaveTask<SD>> taskList, ILogBase _logger)
- {
- bool saveResult = true;
- try
- {
- _logger.Info($"TaskSplitForSave.SaveDatasType:{SaveDatasType};");
- if (taskList == null || taskList.Count() == 0)
- {
- return false;
- }
- int index = 0;
- int sumNum = taskList.Count();
- int syncCallApiNum = sumNum> 0 ? _syncCallApiMaxNum : sumNum;
- while (index <sumNum)
- {
- List<ReportSaveTask<SD>> temp = new List<ReportSaveTask<SD>>();
- syncCallApiNum = syncCallApiNum> sumNum - index ? sumNum - index : syncCallApiNum;
- temp = taskList.GetRange(index, syncCallApiNum);
- index = index + syncCallApiNum;
- System.Threading.Thread.Sleep(5000);
- foreach (var oneT in temp)
- {
- _logger.Info($"start save Report datas to database. start:{index},num:{syncCallApiNum},request:{JsonConvert.SerializeObject(oneT.Data)}");
- oneT.SaveResult.Start();
- }
- Task.WaitAll(temp.Select(each => each.SaveResult).ToArray());
- foreach (var teskOne in temp)
- {
- var saveTempResult = teskOne.SaveResult.Result;
- saveResult = saveResult && saveTempResult;
- if (!saveTempResult)
- {
- _logger.Warn($"failed to async Report datas to database!,request:{JsonConvert.SerializeObject(teskOne.Data)}");
- }
- else
- {
- _logger.Info($"report datas to DB successed!,request:{JsonConvert.SerializeObject(teskOne.Data)}");
- }
- }
- }
- _logger.Info($"TaskSplitForSave result:{JsonConvert.SerializeObject(saveResult)};");
- return saveResult;
- }
- catch (Exception ex)
- {
- _logger.Error($"ProxyReportCallSplit:{ex.ToString()}");
- throw ex;
- }
- }
- private static List<ReportSaveTask<SD>> DataSplitForSave(List<SD> reportDB,Func<List<SD>,bool> saveOperate, ILogBase _logger)
- {
- List<ReportSaveTask<SD>> taskList = new List<ReportSaveTask<SD>>();
- try
- {
- _logger.Info($"DataSplitForSave request.reportDB:{JsonConvert.SerializeObject(reportDB)};");
- if (reportDB == null || reportDB.Count() == 0)
- {
- return null;
- }
- int index = 0;
- int sumNum = reportDB.Count();
- int eachInsert = sumNum> 0 ? _MaxSaveDataNum : sumNum;
- while (index <sumNum)
- {
- List<SD> temp = new List<SD>();
- eachInsert = eachInsert> sumNum - index ? sumNum - index : eachInsert;
- temp = reportDB.GetRange(index, eachInsert);
- index = index + eachInsert;
- var taskTemp = new Task<bool>(()=>saveOperate(temp));//_FacebookReportClient.Save(temp)
- taskList.Add(new ReportSaveTask<SD>() { SaveResult = taskTemp, Data = temp });
- }
- return taskList;
- }
- catch (Exception ex)
- {
- _logger.Error($"save datas to DB error:{ex.ToString()},request:{JsonConvert.SerializeObject(reportDB)}");
- throw ex;
- }
- }
- public static bool ProxyApiSplitToCall(List<Task<List<OD>>> taskList,Func<List<OD>,List<SD>> DateConvertToDB, Func<List<SD>,bool> saveOperate, ILogBase _logger)
- {
- bool result = true;
- try
- {
- _logger.Info($"ProxyApiSplitToCall");
- if (taskList == null || taskList.Count() == 0)
- {
- return false;
- }
- int index = 0;
- int sumNum = taskList.Count();
- int syncCallApiNum = sumNum> 0 ? _syncCallApiMaxNum : sumNum;
- while (index <sumNum)
- {
- syncCallApiNum = syncCallApiNum> sumNum - index ? sumNum - index : syncCallApiNum;
- List<Task<List<OD>>> temp = taskList.GetRange(index, syncCallApiNum);
- index = index + syncCallApiNum;
- System.Threading.Thread.Sleep(5000);
- foreach (var oneT in temp)
- {
- oneT.Start();
- }
- Task.WaitAll(temp.ToArray());
- #region save data
- List<OD> allReports = new List<OD>();
- CommandHelper.UnionAllTaskResult<OD>(temp, ref allReports);
- if (allReports == null || allReports.Count() == 0)
- {
- _logger.Warn($"no datas can get from proxy call![{JsonConvert.SerializeObject(allReports)}]");
- continue;
- }
- _logger.Info($"datas get from proxy call:{JsonConvert.SerializeObject(allReports)}");
- List<SD> reportDB = DateConvertToDB(allReports);
- if (reportDB == null || reportDB.Count() == 0)
- {
- _logger.Warn($"no datas need to be created or updated:{JsonConvert.SerializeObject(reportDB)}");
- continue;
- }
- _logger.Info($"datas need to be save :{JsonConvert.SerializeObject(reportDB)}");
- List<ReportSaveTask<SD>> DataSaveT= DataSplitForSave(reportDB, saveOperate, _logger);
- bool saveResult = TaskSplitForSave(DataSaveT, _logger);
- _logger.Info($"datas save result:{JsonConvert.SerializeObject(saveResult)}");
- #endregion
- result = result & saveResult;
- }
- return result;
- }
- catch (Exception ex)
- {
- _logger.Error($"ProxyReportCallSplit:{ex.ToString()}");
- throw ex;
- }
- }
- }
静态类的使用
bool saveResult = ReportOperation<FacebookDailyReportConvertFromClient, FacebookImpressDeviceReport>.ProxyApiSplitToCall(taskList, dataConvertFunc, dataSaveFunc, _logger);
function 作为参数的使用
- Func<List<FacebookDailyReportConvertFromClient>, List<FacebookImpressDeviceReport>> dataConvertFunc = (originalData) => { return DateConvertToDB(originalData, accounts); };
- Func<List<FacebookImpressDeviceReport>, bool> dataSaveFunc = (saveDB) => { return SaveReportsToDB(saveDB); };
- bool saveResult = ReportOperation<FacebookDailyReportConvertFromClient, FacebookImpressDeviceReport>.ProxyApiSplitToCall(taskList, dataConvertFunc, dataSaveFunc, _logger);
泛型抽象类:
- /// <summary>
- /// get reoports from proxy client
- /// </summary>
- /// <typeparam name="RQ">request type</typeparam>
- /// <typeparam name="RP">response list type</typeparam>
- /// <typeparam name="CRQ">proxy client request type</typeparam>
- /// <typeparam name="CRP">proxy client response type</typeparam>
- public abstract class ReportDownloadBase<RQ, RP,CRQ,CRP> where RQ : class where RP : class where CRQ : class where CRP : class
- {
- protected string exportPath;
- protected System.Collections.Specialized.NameValueCollection appSettings;
- protected ILogBase _logger;
- protected string _plantform;
- public ReportDownloadBase(ILogBase logger,string plantform)
- {
- _plantform = plantform;
- appSettings = WestWin.Common.Configuration.ConfigurationManager.Default.AppSettings;
- exportPath = Path.Combine(System.IO.Directory.GetCurrentDirectory(), appSettings["ReportRawPath"], plantform);
- _logger = logger;
- }
- /// <summary>
- /// Generate ReportRequest for proxy client
- /// </summary>
- /// <param name="req">request</param>
- /// <returns></returns>
- protected abstract CRQ GenerateReportRequest(RQ req);
- /// <summary>
- /// Generate Results to return
- /// </summary>
- /// <param name="resp">ReportResponse</param>
- /// <param name="breakdownValue">breakdownValue </param>
- /// <returns>result list</returns>
- protected abstract List<RP> GenerateResultsByReportResponse(CRP resp, RQ req);
- /// <summary>
- /// get client response from client request
- /// </summary>
- /// <param name="req"></param>
- /// <returns></returns>
- protected abstract CRP GetResponseFromRequest(CRQ req);
- /// <summary>
- /// Get Results By Request
- /// </summary>
- /// <param name="request"></param>
- /// <param name="breakdownValue"></param>
- /// <returns></returns>
- protected List<RP> Process(RQ request,string breakdownValue)
- {
- try
- {
- _logger.Info($"{_plantform} GetReport request:{JsonConvert.SerializeObject(request)}");
- var req = GenerateReportRequest(request);
- _logger.Info($"{_plantform} proxy client request:{JsonConvert.SerializeObject(req)}");
- CRP response = null;
- int maxTry = ConfigHelper.ApiTryMaxNum;
- int count = 0;
- while (count <maxTry)
- {
- count++;
- response = null;
- try
- {
- response = GetResponseFromRequest(req);
- }
- catch (Exception e)
- {
- _logger.Error($"{_plantform} proxy client get report failed:Round {count}", e);
- if(count== maxTry)
- {
- _logger.Error($"{_plantform} proxy client get report: exception & retry time:{count}", e);
- throw e;
- }
- }
- if (response != null) break;
- _logger.Warn($"{_plantform} proxy client get report failed:retry Num: {count},request:{JsonConvert.SerializeObject(req)}");
- System.Threading.Thread.Sleep(5000);
- }
- if (response == null)
- {
- return null;
- }
- _logger.Info($"{_plantform} proxy client Get Report sucess:{JsonConvert.SerializeObject(response)}");
- var result = GenerateResultsByReportResponse(response, request);
- _logger.Info($"{_plantform} return Report result:{JsonConvert.SerializeObject(result)}");
- CommandHelper.CreateDictionaryIfNotExists(exportPath);
- if (result == null || result.Count == 0)
- {
- _logger.Warn($"{_plantform} return empty result for request:{JsonConvert.SerializeObject(req)}");
- }
- else
- {
- var path = Path.Combine(exportPath, $"{_plantform}-row-{breakdownValue}-{DateTime.Now.ToString("yyyyMMddHHmmss")}-{Guid.NewGuid().ToString()}.csv");
- bool saveSucess = CommandHelper.SaveDataToCSVFile<RP>(result, path);
- _logger.Info($"{_plantform} report save local file result:{saveSucess}");
- }
- return result;
- }
- catch (Exception ex)
- {
- _logger.Error($"exception. request.request: {JsonConvert.SerializeObject(request)}; request.breakdownValue: {JsonConvert.SerializeObject(breakdownValue)};error:{ex.ToString()}");
- throw ex;
- }
- }
- }
被使用:
- public class FacebookCountryCmd : ReportDownloadBase<FacebookDailyReportEachRequest, FacebookDailyReportConvertFromClient, FacebookGetAdsInsightRequest, FacebookGetAdsInsightsResponse>, IFacebookCountryCmd
- {
- IFacebookCountryReportService _facebookCountryReportService;
- IFacebookProxyService _FacebookProxyClient;
- IAccountCampaignOperation _campaignOperation;
- IFacebookCampaignHelper _facebookCampaignHelper;
- Platform.Service.Enterprise.AccountChannel _accountChannel = Platform.Service.Enterprise.AccountChannel.Facebook;
- Dictionary<string, FacebookSearchAdgeolocationEntity> _countryDic=new Dictionary<string, FacebookSearchAdgeolocationEntity>();
- public FacebookCountryCmd(ILogBase logger,
IFacebookCountryReportService facebookCountryReportService, IAccountCampaignOperation campaignOperation,
- IFacebookProxyService FacebookProxyClient,IFacebookCampaignHelper facebookCampaignHelper) : base(logger, "facebook")
- {
- _facebookCountryReportService = facebookCountryReportService;
- _FacebookProxyClient = FacebookProxyClient;
- _campaignOperation = campaignOperation;
- _facebookCampaignHelper = facebookCampaignHelper;
- GetAllCountry();
- }
- public List<FacebookCountryReport> DateConvertToDB(List<FacebookDailyReportConvertFromClient> reportDatas, List<BusinessAdsPlatformAccountDetail> accounts)
- {
- //*****
- }
- public void Execute(FacebookCmdOptions opt)
- {
- //*****
- }
- public bool SaveReportsToDB(List<FacebookCountryReport> reportDB)
- {
- //****
- }
- protected override FacebookGetAdsInsightRequest GenerateReportRequest(FacebookDailyReportEachRequest req)
- {
- //****
- }
- protected override List<FacebookDailyReportConvertFromClient> GenerateResultsByReportResponse(FacebookGetAdsInsightsResponse response, FacebookDailyReportEachRequest req)
- {
- //***
- }
- protected override FacebookGetAdsInsightsResponse GetResponseFromRequest(FacebookGetAdsInsightRequest req)
- {
- //****
- }
- private bool IfNextPage(FacebookGetAdsInsightsResponse response, ref FacebookGetAdsInsightRequest request)
- {
- //****
- }
- }
- public interface IFacebookCountryCmd: IReportCmdBase<FacebookCountryReport, FacebookCmdOptions, FacebookDailyReportConvertFromClient>
- {
- }
- /// <summary>
- /// execute download report
- /// </summary>
- /// <typeparam name="RDB">report type define by DB</typeparam>
- /// <typeparam name="CMD">command type</typeparam>
- /// <typeparam name="RP">report response including all data get from proxy client</typeparam>
- public interface IReportCmdBase<RDB,CMD,RP> where RDB : class where CMD:class where RP:class
- {
- /// <summary>
- /// Save Reports To DB
- /// </summary>
- /// <param name="reportDB"></param>
- /// <returns></returns>
- bool SaveReportsToDB(List<RDB> reportDB);
- /// <summary>
- /// convert report to match datebase define
- /// </summary>
- /// <param name="reportDatas"></param>
- /// <returns></returns>
- List<RDB> DateConvertToDB(List<RP> reportDatas, List<BusinessAdsPlatformAccountDetail> accounts);
- /// <summary>
- /// Execute Download Report :get from proxy client api & save original data to local file & save to DB
- /// </summary>
- /// <param name="opt">command</param>
- void Execute(CMD opt);
- }
- c# 泛型的应用
来源: http://www.bubuko.com/infodetail-2622793.html