如何在C#中执行时间记录器类包装器
问题描述:
我有很多(大约一千)FluentMigrator
Migration
类在我们的构建服务器上开始超时。如何在C#中执行时间记录器类包装器
对于那些谁也不会FluentMigrator
工作 - 迁移以这样的方式工作,所有的迁移从有对数据库迁移运行SQL脚本Up()
和Down()
方法Migration
类继承 - 简单和容易。
现在懒惰我已经引入了一个LoggingMigration
类,它记录了迁移开始运行的时间(并且简单地将该项目的VS中的: Migration
替换为: LoggingMigration
)。
public class LoggingMigration : Migration
{
public DateTime StartTime { get; private set; }
public LoggingMigration()
{
this.StartTime = DateTime.Now;
Console.WriteLine("Start {0} - TIME: {1:yyyy-MM-dd HH:mm:ss.fff}", this.GetType().Name, StartTime);
}
public override void Up()
{
}
public override void Down()
{
}
}
我想也做长期的迁移正在运行如何使它更容易看到哪些迁移多久的时间。
我在考虑使用析构函数一样的:
~LoggingMigration()
{
Console.WriteLine("End(?) {0} - TIME: {1}", this.GetType().Name, DateTime.Now.Subtract(StartTime));
}
但事情仅仅是volatile and unpredictable
如何添加,将在后子类饰面Up()
方法运行机制? 或者其他一些可以完成这项工作的方式?
答
如何覆盖一个受保护的方法,而不是公共之一:
public abstract class Migration
{
// ...
protected DateTime StartTime { get; private set; }
public Migration()
{
this.StartTime = DateTime.Now;
Console.WriteLine("Start {0} - TIME: {1:yyyy-MM-dd HH:mm:ss.fff}", this.GetType().Name, StartTime);
}
public void Up()
{
OverrideUp();
Console.WriteLine("End(?) {0} - TIME: {1}", this.GetType().Name, DateTime.Now.Substracts(StartTime));
}
public void Down()
{
// ...
OverrideDown();
}
protected abstract void OverrideUp();
protected abstract void OverrideDown();
}
答
创建迁移类的装饰。 它看起来像:Decorator模式
public class LoggingMigrationDecorator : Migration {
private Migration _migrationClass;
public DateTime StartTime { get; private set; }
public LoggingMigrationDecorator (Migration toDecorate)
{
_migrationClass = toDecorate;
this.StartTime = DateTime.Now;
Console.WriteLine("Start {0} - TIME: {1:yyyy-MM-dd HH:mm:ss.fff}", this.GetType().Name, StartTime);
}
public override void Up()
{
toDecorate.Up();
stopTimerFunction(); // your function that will stop timer and do something with result
}
public override void Down()
{
}
}
}
嗨马特,我不能修改移民类它来自FluentMigrator但我可以介绍是从迁移继承类(如LoggingMigrator)。您建议在所有当前迁移中用'OverrideUp()'替换'Up()'是否正确? –
@MatasVaitkevicius没错。无论是或者你可以使用自定义属性,但我会坚持面向对象的方式。 –