Skip to content

Instantly share code, notes, and snippets.

@oguzhaneren
Created January 2, 2015 14:23
Show Gist options
  • Save oguzhaneren/202267362af027a6e523 to your computer and use it in GitHub Desktop.
Save oguzhaneren/202267362af027a6e523 to your computer and use it in GitHub Desktop.
NHibernate Domain Event Publisher
public class FooEntity
: IHaveEvents
{
private readonly IList<IEvent> _events = new List<IEvent>();
private readonly ICollection<FooMember> _members = new HashedSet<FooMember>();
public virtual Guid Id { get; protected set; }
public virtual IEnumerable<FooMember> Members { get { return _members; } }
public IList<IEvent> Events { get { return _events; } }
public void AddMember(string memberName)
{
_members.Add(new FooMember(memberName));
_events.Add(new MemberAdded(Id, memberName));
}
}
public class MemberAdded : IEvent
{
public Guid FooId { get; protected set; }
public string MemberName { get; protected set; }
public MemberAdded(Guid id, string memberName)
{
MemberName = memberName;
FooId = id;
}
}
public class FooMember
{
public virtual string Name { get; protected set; }
public FooMember(string name)
{
Name = name;
}
protected FooMember() { }
}
public interface IHaveEvents
{
IList<IEvent> Events { get; }
}
public interface IEvent { }
public static class NhExtensions
{
public static void PublishEvents(this ISession session)
{
var sessionImpl = session.GetSessionImplementation();
var persistenceContext = sessionImpl.PersistenceContext;
var changedObjects = (from EntityEntry entityEntry in persistenceContext.EntityEntries.Values
select persistenceContext.GetEntity(entityEntry.EntityKey))
.OfType<IHaveEvents>()
.Where(ev => ev.Events.Count > 0)
.ToList();
foreach (var entity in changedObjects)
{
foreach (var ev in entity.Events)
{
DomainEvents.Publish(ev);
}
entity.Events.Clear();
}
}
}
public class NHibernateTransactionWebApiFilter
: ActionFilterAttribute
{
public NHibernateTransactionWebApiFilter()
{
IsolationLevel = IsolationLevel.Unspecified;
}
public ISession Session
{
get { return ServiceLocator.Current.GetInstance<ISession>(); }
}
public bool RollbackOnModelStateError { get; set; }
public IsolationLevel IsolationLevel { get; set; }
public override void OnActionExecuting(HttpActionContext actionContext)
{
Session.BeginTransaction(IsolationLevel);
}
public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
{
if (Session == null)
return;
using (Session)
{
var transaction = Session.Transaction;
if (transaction == null || transaction.IsActive == false)
return;
using (transaction)
{
if (ShouldRollback(actionExecutedContext))
{
transaction.Rollback();
}
else
{
Session.PublishEvents();
transaction.Commit();
}
Session.Close();
}
}
}
private static bool ShouldRollback(HttpActionExecutedContext fc)
{
return fc.Exception != null;
}
}
@oguzhaneren
Copy link
Author

for DomainEvents details and implementation: http://www.udidahan.com/2009/06/14/domain-events-salvation/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment