using System;
using System.Reflection;
using System.Transactions;
using Xunit.Sdk;
namespace Bootstrap.DataAccess
{
///
/// Apply this attribute to your test method to automatically create a
/// that is rolled back when the test is finished.
///
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public sealed class AutoRollbackAttribute : BeforeAfterTestAttribute
{
private TransactionScope scope;
///
/// Gets or sets whether transaction flow across thread continuations is enabled for TransactionScope.
/// By default transaction flow across thread continuations is enabled.
///
public TransactionScopeAsyncFlowOption AsyncFlowOption { get; set; } = TransactionScopeAsyncFlowOption.Enabled;
///
/// Gets or sets the isolation level of the transaction.
/// Default value is .Unspecified.
///
public IsolationLevel IsolationLevel { get; set; } = IsolationLevel.Unspecified;
///
/// Gets or sets the scope option for the transaction.
/// Default value is .Required.
///
public TransactionScopeOption ScopeOption { get; set; } = TransactionScopeOption.Required;
///
/// Gets or sets the timeout of the transaction, in milliseconds.
/// By default, the transaction will not timeout.
///
public long TimeoutInMS { get; set; } = -1;
///
/// Rolls back the transaction.
///
public override void After(MethodInfo methodUnderTest)
{
scope.Dispose();
}
///
/// Creates the transaction.
///
public override void Before(MethodInfo methodUnderTest)
{
var options = new TransactionOptions { IsolationLevel = IsolationLevel };
if (TimeoutInMS > 0)
options.Timeout = TimeSpan.FromMilliseconds(TimeoutInMS);
scope = new TransactionScope(ScopeOption, options, AsyncFlowOption);
}
}
}