public void CannotAquireLockIfLockAlreadyAquired()
            {
                var aggregateId = GuidStrategy.NewGuid();
                using (var aggregateLock = new AggregateLock(typeof(Aggregate), aggregateId))
                {
                    aggregateLock.Aquire();
                    var ex = Assert.Throws<InvalidOperationException>(() => aggregateLock.Aquire());

                    Assert.Equal(Exceptions.AggregateLockAlreadyHeld.FormatWith(typeof(Aggregate), aggregateId), ex.Message);
                }
            }
            public void CannotAquireLockIfLockAlreadyAquired()
            {
                var aggregateId = GuidStrategy.NewGuid();

                using (var aggregateLock = new AggregateLock(typeof(Aggregate), aggregateId))
                {
                    aggregateLock.Aquire();
                    var ex = Assert.Throws <InvalidOperationException>(() => aggregateLock.Aquire());

                    Assert.Equal(Exceptions.AggregateLockAlreadyHeld.FormatWith(typeof(Aggregate), aggregateId), ex.Message);
                }
            }
            public void AquireWillBlockIfAnotherLockAlreadyAquiredOnSameAggregate()
            {
                var correlationId = GuidStrategy.NewGuid();
                var firstLockAquired = new ManualResetEvent(initialState: false);
                var secondLockAquired = new ManualResetEvent(initialState: false);
                var blockedTime = TimeSpan.Zero;

                Task.Factory.StartNew(() =>
                {
                    firstLockAquired.WaitOne();
                    using (var aggregateLock = new AggregateLock(typeof(Aggregate), correlationId))
                    {
                        var timer = Stopwatch.StartNew();

                        aggregateLock.Aquire();
                        timer.Stop();

                        blockedTime = timer.Elapsed;
                        secondLockAquired.Set();
                    }
                });

                using (var aggregateLock = new AggregateLock(typeof(Aggregate), correlationId))
                {
                    aggregateLock.Aquire();
                    firstLockAquired.Set();

                    Thread.Sleep(100);
                }

                secondLockAquired.WaitOne();

                Assert.InRange(blockedTime, TimeSpan.FromMilliseconds(50), TimeSpan.FromMilliseconds(150));
            }
            public void AquireWillNotBlockIfAnotherLockAlreadyAquiredOnAnotherAggregate()
            {
                var firstLockAquired  = new ManualResetEvent(initialState: false);
                var secondLockAquired = new ManualResetEvent(initialState: false);
                var blockedTime       = TimeSpan.Zero;

                Task.Factory.StartNew(() =>
                {
                    firstLockAquired.WaitOne();
                    using (var aggregateLock = new AggregateLock(typeof(Aggregate), GuidStrategy.NewGuid()))
                    {
                        var timer = Stopwatch.StartNew();

                        aggregateLock.Aquire();
                        timer.Stop();

                        blockedTime = timer.Elapsed;
                        secondLockAquired.Set();
                    }
                });

                using (var aggregateLock = new AggregateLock(typeof(Aggregate), GuidStrategy.NewGuid()))
                {
                    aggregateLock.Aquire();
                    firstLockAquired.Set();

                    Thread.Sleep(100);
                }

                secondLockAquired.WaitOne();

                Assert.InRange(blockedTime, TimeSpan.FromMilliseconds(0), TimeSpan.FromMilliseconds(50));
            }
            public void CanDisposeIfLockAquired()
            {
                var aggregateLock = new AggregateLock(typeof(Aggregate), GuidStrategy.NewGuid());

                aggregateLock.Aquire();

                aggregateLock.Dispose();
            }
            public void CanAquireLockIfNoLockAquired()
            {
                using (var aggregateLock = new AggregateLock(typeof(Aggregate), GuidStrategy.NewGuid()))
                {
                    aggregateLock.Aquire();

                    Assert.True(aggregateLock.Aquired);
                }
            }
            public void CanAquireLockIfNoLockAquired()
            {
                using (var aggregateLock = new AggregateLock(typeof(Aggregate), GuidStrategy.NewGuid()))
                {
                    aggregateLock.Aquire();

                    Assert.True(aggregateLock.Aquired);
                }
            }
            public void CanReleaseLockIfLockAquired()
            {
                using (var aggregateLock = new AggregateLock(typeof(Aggregate), GuidStrategy.NewGuid()))
                {
                    aggregateLock.Aquire();
                    aggregateLock.Release();

                    Assert.False(aggregateLock.Aquired);
                }
            }
            public void CanDisposeMoreThanOnce()
            {
                var aggregateLock = new AggregateLock(typeof(Aggregate), GuidStrategy.NewGuid());

                aggregateLock.Aquire();
                aggregateLock.Dispose();

                aggregateLock.Dispose();
            }
            public void CanReleaseLockIfLockAquired()
            {
                using (var aggregateLock = new AggregateLock(typeof(Aggregate), GuidStrategy.NewGuid()))
                {
                    aggregateLock.Aquire();
                    aggregateLock.Release();

                    Assert.False(aggregateLock.Aquired);
                }
            }