每個專案都要在 web.config 或程式碼中重複寫入 hibernate.connection.driver_class、dialect、connection_string 等鍵值,易出錯且難以切換資料庫。
public abstract class ActiveRecordInitializer
{
public abstract void Initialize(string databaseName, string modelAssembly);
}
public class SqlServerInitializer : ActiveRecordInitializer
{
public override void Initialize(string databaseName, string modelAssembly)
{
var properties = new Hashtable
{
["hibernate.connection.driver_class"] = "NHibernate.Driver.SqlClientDriver",
["hibernate.dialect"] = "NHibernate.Dialect.MsSql2000Dialect",
["hibernate.connection.provider"] = "NHibernate.Connection.DriverConnectionProvider",
["hibernate.connection.connection_string"] =
$"Data Source=.;Initial Catalog={databaseName};Integrated Security=SSPI"
};
var source = new InPlaceConfigurationSource();
source.Add(typeof(ActiveRecordBase), properties);
ActiveRecordStarter.Initialize(Assembly.Load(modelAssembly), source);
ActiveRecordStarter.CreateSchema();
}
}
public class MySqlInitializer : ActiveRecordInitializer
{
public override void Initialize(string databaseName, string modelAssembly)
{
var properties = new Hashtable
{
["hibernate.connection.driver_class"] = "NHibernate.Driver.MySqlDataDriver",
["hibernate.dialect"] = "NHibernate.Dialect.MySQLDialect",
["hibernate.connection.provider"] = "NHibernate.Connection.DriverConnectionProvider",
["hibernate.connection.connection_string"] =
$"Server=localhost;Database={databaseName};Uid=root;Pwd=123;CharSet=utf8;"
};
var source = new InPlaceConfigurationSource();
source.Add(typeof(ActiveRecordBase), properties);
ActiveRecordStarter.Initialize(Assembly.Load(modelAssembly), source);
ActiveRecordStarter.CreateSchema();
}
}
public static class ActiveRecordFactory
{
public static ActiveRecordInitializer Create(string dbType)
{
return dbType.ToUpper() switch
{
"SQL" => new SqlServerInitializer(),
"MYSQL" => new MySqlInitializer(),
_ => new SqlServerInitializer()
};
}
}
// 在 Global.asax Application_Start 中
var initializer = ActiveRecordFactory.Create("SQL"); // 或 "MYSQL"
initializer.Initialize("MyDatabase", "MyProject.Model");
appSettings 讀取)。PostgreSQL、Oracle、SQLite 只需新增對應 Initializer。CreateSchema(),改用 FluentMigrator 或 Flyway 管理版本。ActiveRecordInitializer 介面,實現完全解耦。透過**工廠模式 + 策略模式**封裝 ActiveRecord 初始化邏輯,達到: