我正在寻找一些关于 POCO 实例可以做什么的建议,这些实例是由 Nhibernate 延迟加载的(如果有什么不同的话,Fluent NHibernate)。
我正在研究更改日志记录的通用实现。进行完全自定义实现的原因是更改数据必须以非常特定的格式写入以用于不同目的。并非所有需要的信息都可以直接从 POCO 实例访问,而是必须进行计算。最终结果是,更改数据将被写入与操作数据库分开的数据库。写入数据的行为将使用 SqlCommand 完成。
因为实现必须是通用的以支持当前的 POCO 类以及任何未来的添加,它将使用反射来提取传递给更改日志实现的 POCO 的属性。
我所拥有的是:
public interface IChangeLogger
{
void Log(BaseEntity entity);
}
其中 BaseEntity 是每个 POCO 都继承自的类。
实现是
public class DefaultChangeLogger : IChangeLogger
{
private readonly string _connectionString;
public DefaultChangeLogger()
{
var connectionString = ConfigurationManager.ConnectionStrings["ChangeLogger"];
Guard.Against<ConfigurationErrorsException>(connectionString == null || string.IsNullOrEmpty(connectionString.ConnectionString));
_connectionString = connectionString.ConnectionString;
}
public void LogChange(BaseEntity entity)
{
var logger = new SqlServerDirectChangeLogger(_connectionString, entity);
var starter = new ThreadStart(logger.Log);
var workerThread = new Thread(starter) { IsBackground = true };
workerThread.Start();
}
}
最后是最终的工人实现:
public class SqlServerDirectChangeLogger
{
private readonly string _connectionString;
private readonly BaseEntity _entity;
public SqlServerDirectChangeLogger(string connectionString, BaseEntity entity)
{
_connectionString = connectionString;
_entity = entity;
}
public void Log()
{
}
}
拥有单独线程的原因不是为了阻止应用程序(MVC3、IIS7.5),而是在低优先级后台线程中进行格式化和登录。当前端用户更新记录时,我不想延迟响应,因为记录器需要同步进行。
所以 SqlServerDirectChangeLogger.Log() 将做的是使用反射来提取属性值并加载一些额外的元数据,然后将这些元数据写入单独的数据库中以键值形式更改日志表。
问题如下:
- Web 应用程序使用范围为 PerWebRequest 的 ISession。DefaultChangeLogger 将具有 Singleton 的生命周期。如果我传入延迟加载 POCO 并评估可能触发延迟加载的属性,则需要打开 ISession。ISession 可能会在需要时关闭。
是否可以让 NHibernate “完成” POCO 实例?通过最终确定,我的意思是强制延迟加载到某个级别并可能断开 ISession?
我可以通过在 IIS 工作线程和派生的工作线程之间传递像上面这样的实例来预测任何其他问题吗?
关于如何实现更改日志的任何更好的想法?:)
感谢您的任何见解。