ระบบที่ฉันกำลังใช้งานอยู่ใช้สถาปัตยกรรมที่ขับเคลื่อนด้วยเหตุการณ์และการส่งข้อความเพื่อให้การกระทำส่วนใหญ่ในระบบของเราเป็นผลมาจากคำสั่งและพวกเขาส่งผลให้เกิดเหตุการณ์ (ในชั้นเรียน DTO ที่ถูกส่งมากกว่าเหตุการณ์ตัวแทนมาตรฐาน) เราแนบตัวจัดการเหตุการณ์โดยมีวัตถุประสงค์เพื่อจัดการการบันทึกเท่านั้น การออกแบบนี้ช่วยให้เราไม่ต้องทำซ้ำตัวเองและไม่ต้องแก้ไขรหัสที่มีอยู่เพื่อเพิ่ม / เปลี่ยนฟังก์ชั่น
นี่คือตัวอย่างของคลาสการบันทึกหนึ่งคลาสที่จัดการเหตุการณ์ทั้งหมดที่จะถูกบันทึกจากส่วนที่แคบของแอปพลิเคชันของเรา (ที่เกี่ยวข้องกับแหล่งเนื้อหาหนึ่งที่เรานำเข้ามา)
ฉันไม่จำเป็นต้องพูดว่านี่เป็นวิธีปฏิบัติที่ดีที่สุดเนื่องจากฉันเปลี่ยนใจในสิ่งที่และวิธีการเข้าสู่ระบบบ่อยครั้ง - และทุกครั้งที่ฉันต้องใช้บันทึกเพื่อวิเคราะห์ปัญหาฉันย่อมหาวิธีที่จะปรับปรุง ข้อมูลที่ฉันบันทึก
ฉันจะบอกว่าการบันทึกข้อมูลที่เกี่ยวข้อง (โดยเฉพาะอย่างยิ่งใน Ctrl-F / ค้นหาวิธีที่ค้นหาได้) เป็นส่วนที่สำคัญที่สุด
ส่วนที่สำคัญที่สุดที่สองจะได้รับรหัสการเข้าสู่ระบบออกจากตรรกะหลักของคุณ - มันสามารถทำให้วิธีการที่น่าเกลียดและระยะยาวและซับซ้อนมากได้อย่างรวดเร็ว
public class MctLogger :
IEventHandler<StoryImported>,
IEventHandler<StoryScanned>,
IEventHandler<SourceDirectoryMissing>,
IEventHandler<SourceDirectoryAccessError>,
IEventHandler<CannotCreateScannedStoryDirectory>,
IEventHandler<CannotReadStoryDocument>,
IEventHandler<StorySkippedPastCutoff>,
IEventHandler<StorySkippedDuplicateUniqueId>,
IEventHandler<StorySkippedByFilter>
{
public void Observe(StoryImported e)
{
var log = Slf.LoggerService.GetLogger("RoboChef.Content.Mct.StoryImported");
log.Info("Story Unique ID: {Story.UniqueId}, Content ID: {ContentId}, Title: {Story.Headline}".SmartFormat(e));
}
public void Observe(StoryScanned e)
{
var log = Slf.LoggerService.GetLogger("RoboChef.Content.Mct.StoryScanned");
log.Info("Story Unique ID: {Story.UniqueId}, File: {FilePath}, Title: {Story.Headline}".SmartFormat(e));
}
public void Observe(SourceDirectoryMissing e)
{
var log = Slf.LoggerService.GetLogger("RoboChef.Content.Mct.SourceDirectoryMissing");
log.Error("Directory: " + e.Directory);
}
public void Observe(SourceDirectoryAccessError e)
{
var log = Slf.LoggerService.GetLogger("RoboChef.Content.Mct.SourceDirectoryAccessError");
log.Error(e.Exception, "Exception: " + e.Exception.Message);
}
public void Observe(CannotCreateScannedStoryDirectory e)
{
var log = Slf.LoggerService.GetLogger("RoboChef.Content.Mct.CannotCreateScannedStoryDirectory");
log.Error(e.Exception, "Directory: {Directory}, Exception: {Exception.Message}".SmartFormat(e));
}
public void Observe(CannotReadStoryDocument e)
{
var log = Slf.LoggerService.GetLogger("RoboChef.Content.Mct.CannotReadStoryDocument");
if (e.Exception == null) {
log.Warn("File: {FilePath}".SmartFormat(e));
}
else {
log.Warn(e.Exception, "File: {FilePath}, Exception: {Exception.Message}".SmartFormat(e));
}
}
public void Observe(StorySkippedPastCutoff e)
{
var log = Slf.LoggerService.GetLogger("RoboChef.Content.Mct.StorySkippedPastCutoff");
log.Warn("Story Unique ID: {Story.UniqueId}, File: {FilePath}, Title: {Story.Headline}".SmartFormat(e));
}
public void Observe(StorySkippedDuplicateUniqueId e)
{
var log = Slf.LoggerService.GetLogger("RoboChef.Content.Mct.StorySkippedDuplicateUniqueId");
log.Warn("Story Unique ID: {Story.UniqueId}, File: {FilePath}, Title: {Story.Headline}".SmartFormat(e));
}
public void Observe(StorySkippedByFilter e)
{
var log = Slf.LoggerService.GetLogger("RoboChef.Content.Mct.StorySkippedByFilter");
log.Warn("Story Unique ID: {Story.UniqueId}, Reason: {Reason}, File: {FilePath}, Title: {Story.Headline}".SmartFormat(e));
}
}