Skip to content

Instantly share code, notes, and snippets.

@plioi
Created January 27, 2016 00:52
Show Gist options
  • Save plioi/481eaa2f474a14b6c936 to your computer and use it in GitHub Desktop.
Save plioi/481eaa2f474a14b6c936 to your computer and use it in GitHub Desktop.
public static class Testing
{
private static IContainer Container => TestDependencyScope.CurrentNestedContainer;
public static T Resolve<T>()
{
return Container.GetInstance<T>();
}
public static object Resolve(Type type)
{
return Container.GetInstance(type);
}
public static void Inject<T>(T instance) where T : class
{
Container.Inject(instance);
}
public static void LogSql()
{
Resolve<ContactsContext>().Database.Log = Console.Write;
}
public static void Transaction(Action<ContactsContext> action)
{
using (var database = new ContactsContext())
{
try
{
database.BeginTransaction();
action(database);
database.CloseTransaction();
}
catch (Exception exception)
{
database.CloseTransaction(exception);
throw;
}
}
}
public static void Save(params object[] entities)
{
Resolve<SaveAtMostOncePolicy>().Enforce();
Transaction(database =>
{
foreach (var entity in entities)
database.Set(entity.GetType()).Add(entity);
});
}
private class SaveAtMostOncePolicy
{
private bool _hasAlreadySaved;
public void Enforce()
{
if (_hasAlreadySaved)
throw new InvalidOperationException(
"A test should call Save(...) at most once. Otherwise, " +
"it is likely that duplicate records will be created, as each " +
"call to this method uses a distinct DbContext.");
_hasAlreadySaved = true;
}
}
public static TResult Query<TResult>(Func<ContactsContext, TResult> query)
{
var result = default(TResult);
Transaction(database =>
{
result = query(database);
});
return result;
}
public static IValidator Validator<TResult>(IRequest<TResult> message)
{
var validatorType = typeof(IValidator<>).MakeGenericType(message.GetType());
return Container.TryGetInstance(validatorType) as IValidator;
}
public static void Send(IRequest message)
{
Send((IRequest<Unit>)message);
}
public static TResult Send<TResult>(IRequest<TResult> message)
{
var validator = Validator(message);
if (validator != null)
message.ShouldValidate();
TResult result;
var database = Resolve<ContactsContext>();
try
{
database.BeginTransaction();
result = Resolve<IMediator>().Send(message);
database.CloseTransaction();
}
catch (Exception exception)
{
database.CloseTransaction(exception);
throw;
}
return result;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment