NHibernate Step By Step(4)-事件(Event)
2009-08-02 23:23 Clingingboy 阅读(1015) 评论(0) 编辑 收藏 举报除了拦截器,NH还有事件机制,与拦截器不同,这些事件全部与操作有关进行分拆,这其实是一件相当大的工作量,因为着session的每个操作都会有对应的事件,对使用者而言,灵活度则增加了.所以在NHibernate.Event命名空间下,命名了大量的事件监听接口与session操作相对应,在NHibernate.Action命名空间下继承自IExecutable的接口则对这些接口进行调用.
ListenerType枚举,列出了全部的事件类别
/// <summary> /// Values for listener type property. /// </summary> public enum ListenerType { /// <summary>Not allowed in Xml. It represents the default value when an explicit type is assigned.</summary> NotValidType, /// <summary>Xml value: auto-flush</summary> Autoflush, /// <summary>Xml value: merge</summary> Merge, /// <summary>Xml value: create</summary> Create, /// <summary>Xml value: create-onflush</summary> CreateOnFlush, /// <summary>Xml value: delete</summary> Delete, /// <summary>Xml value: dirty-check</summary> DirtyCheck, /// <summary>Xml value: evict</summary> Evict, /// <summary>Xml value: flush</summary> Flush, /// <summary>Xml value: flush-entity</summary> FlushEntity, /// <summary>Xml value: load</summary> Load, /// <summary>Xml value: load-collection</summary> LoadCollection, /// <summary>Xml value: lock</summary> Lock, /// <summary>Xml value: refresh</summary> Refresh, /// <summary>Xml value: replicate</summary> Replicate, /// <summary>Xml value: save-update</summary> SaveUpdate, /// <summary>Xml value: save</summary> Save, /// <summary>Xml value: pre-update</summary> PreUpdate, /// <summary>Xml value: update</summary> Update, /// <summary>Xml value: pre-load</summary> PreLoad, /// <summary>Xml value: pre-delete</summary> PreDelete, /// <summary>Xml value: pre-insert</summary> PreInsert, /// <summary>Xml value: pre-collection-recreate </summary> PreCollectionRecreate, /// <summary>Xml value: pre-collection-remove </summary> PreCollectionRemove, /// <summary>Xml value: pre-collection-update </summary> PreCollectionUpdate, /// <summary>Xml value: post-load</summary> PostLoad, /// <summary>Xml value: post-insert</summary> PostInsert, /// <summary>Xml value: post-update</summary> PostUpdate, /// <summary>Xml value: post-delete</summary> PostDelete, /// <summary>Xml value: post-commit-update</summary> PostCommitUpdate, /// <summary>Xml value: post-commit-insert</summary> PostCommitInsert, /// <summary>Xml value: post-commit-delete</summary> PostCommitDelete, /// <summary>Xml value: post-collection-recreate </summary> PostCollectionRecreate, /// <summary>Xml value: post-collection-remove </summary> PostCollectionRemove, /// <summary>Xml value: post-collection-update </summary> PostCollectionUpdate, }
这一设计让人感觉到NH设计工作的繁重,与内部操作仅仅相连,修改一个操作的话就要为了这些特性而修改.可能这也是必要的工作吧.
还是贴些代码来的实在
public delegate void AssertionAction(PostUpdateEvent @event); public class AssertOldStatePostListener : IPostUpdateEventListener { private readonly AssertionAction assertionDelegate; public AssertOldStatePostListener(AssertionAction assertionDelegate) { this.assertionDelegate = assertionDelegate; } public const string LogMessage = "PostUpdateEvent called."; private static readonly ILog log = LogManager.GetLogger(typeof(AssertOldStatePostListener)); public void OnPostUpdate(PostUpdateEvent @event) { log.Debug(LogMessage); assertionDelegate(@event); } }
注意这里操作完成后将赋值的事件重新赋值了
[Test] public void ImplicitFlush() { ((SessionFactoryImpl) sessions).EventListeners.PostUpdateEventListeners = new IPostUpdateEventListener[] { new AssertOldStatePostListener( eArgs => Assert.That(eArgs.OldState, Is.Not.Null)) }; FillDb(); using (var ls = new LogSpy(typeof (AssertOldStatePostListener))) { using (ISession s = OpenSession()) { using (ITransaction tx = s.BeginTransaction()) { IList<SimpleEntity> l = s.CreateCriteria<SimpleEntity>().List<SimpleEntity>(); l[0].Description = "Modified"; tx.Commit(); } } Assert.That(ls.GetWholeLog(), Text.Contains(AssertOldStatePostListener.LogMessage)); } DbCleanup(); ((SessionFactoryImpl) sessions).EventListeners.PostUpdateEventListeners = new IPostUpdateEventListener[0]; }