Skip to content

Instantly share code, notes, and snippets.

@johanclasson
Last active March 24, 2016 15:57
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 johanclasson/056d08a5e50264dda7cf to your computer and use it in GitHub Desktop.
Save johanclasson/056d08a5e50264dda7cf to your computer and use it in GitHub Desktop.
using System;
using System.Data.Common;
using Microsoft.Data.Entity;
using Microsoft.Data.Sqlite;
using Microsoft.Extensions.DependencyInjection;
namespace EF.TestUtils
{
public sealed class TestContextFactory : IDisposable
{
private IDisposable _connection;
private IDisposable _scope;
private int _index;
private static readonly object Locker = new object();
public TContext CreateInMemoryDatabase<TContext>() where TContext : DbContext
{
var serviceCollection = new ServiceCollection();
serviceCollection.AddEntityFramework().AddInMemoryDatabase()
.AddDbContext<TContext>(c => c.UseInMemoryDatabase());
var serviceProvider = serviceCollection.BuildServiceProvider();
var scope = serviceProvider.GetRequiredService<IServiceScopeFactory>().CreateScope();
_scope = scope;
return scope.ServiceProvider.GetService<TContext>();
}
public TContext CreateInMemorySqlite<TContext>(bool migrate = true) where TContext : DbContext
{
string connectionString = CreateSqliteSharedInMemoryConnectionString();
DbConnection connection = OpenConnectionToKeepInMemoryDbUntilDispose(connectionString);
var dbContext = CreateSqliteDbContext<TContext>(connection);
if (migrate)
dbContext.Database.Migrate();
return dbContext;
}
private string CreateSqliteSharedInMemoryConnectionString()
{
string name = GetUniqueName();
return $"Data Source={name};Mode=Memory;Cache=Shared";
}
private string GetUniqueName()
{
lock (Locker)
{
return $"testdb{++_index}.db";
}
}
private DbConnection OpenConnectionToKeepInMemoryDbUntilDispose(string connectionString)
{
var connection = new SqliteConnection(connectionString);
connection.Open();
_connection = connection;
return connection;
}
private TContext CreateSqliteDbContext<TContext>(DbConnection connection) where TContext : DbContext
{
var serviceCollection = new ServiceCollection();
serviceCollection.AddEntityFramework().AddSqlite()
.AddDbContext<TContext>(c => c.UseSqlite(connection));
IServiceProvider serviceProvider = serviceCollection.BuildServiceProvider();
var scope = serviceProvider.GetRequiredService<IServiceScopeFactory>().CreateScope();
_scope = scope;
return scope.ServiceProvider.GetService<TContext>();
}
public void Dispose()
{
_connection?.Dispose();
_scope?.Dispose();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment