Skip to content

Instantly share code, notes, and snippets.

Created January 8, 2013 14:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save anonymous/4484261 to your computer and use it in GitHub Desktop.
Save anonymous/4484261 to your computer and use it in GitHub Desktop.
Expirable invariants in DDD
public class Expirable<T> : IValueObject<Expirable<T>>
{
public T Value { get; protected set; }
public DateTime ValidTill { get; protected set; }
protected Expirable()
{
}
public Expirable(T value, DateTime validTill)
{
Value = value;
ValidTill = validTill;
}
}
public class NHibernateRepository<T> : IRepository<T> where T : class, IEntity
{
protected readonly ISession session;
public NHibernateRepository(ISession session)
{
this.session = session;
}
protected void InvalidateExpirable<TExpirableValue>(Expression<Func<T, IEnumerable<Expirable<TExpirableValue>>>> selector, Action<T, Expirable<TExpirableValue>> remover)
{
var memberName = selector.GetMemberName();
var query = string.Format(
"select u as Entity, us.Value as ExpirableValue, us.ValidTill as ExpirableValidTill from {0} u join fetch u.{1} us where us.ValidTill < :now",
typeof(T).Name,
memberName
);
var entries = session
.CreateQuery(query)
.SetParameter("now", SystemTime.Now())
.SetResultTransformer(Transformers.AliasToBean<ExpiredDto<T, TExpirableValue>>())
.List<ExpiredDto<T, TExpirableValue>>();
foreach (var entry in entries)
{
remover(entry.Entity, entry.AsExpirable());
}
}
}
public class User : IEntity, IEquatable<User>
{
private readonly IList<Expirable<UserSession>> sessions = new List<Expirable<UserSession>>();
public virtual string Username { get; protected set; }
public virtual string Email { get; protected set; }
public virtual string Salt { get; protected set; }
public virtual string Password { get; protected set; }
public virtual IEnumerable<Expirable<UserSession>> Sessions { get { return sessions; } }
public virtual void RemoveSession(Expirable<UserSession> sess)
{
if (Sessions == null || !Sessions.Any())
{
return;
}
Expirable<UserSession> userSession = sessions.FirstOrDefault(s => s.Equals(sess));
if (userSession == null)
{
return;
}
sessions.Remove(userSession);
DomainEvents.Raise(
new UserSessionTerminatedEvent(
userId: Id,
validTill: userSession.ValidTill,
ipAddress: userSession.Value.IpAddress,
started: userSession.Value.Started,
token: userSession.Value.Token
)
);
}
public class UserRepository : NHibernateRepository<User>
{
public UserRepository(ISession session) : base(session)
{
InvalidateExpirable(x => x.Sessions, (e, exp) => e.RemoveSession(exp));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment