I just got this job:
public static class DbContextUtils { private const BindingFlags PrivateInstance = BindingFlags.NonPublic | BindingFlags.Instance; public static T CreateDbContext<T>() where T : DbContext { return CreateDbContext<T>(GetProfiledConnection<T>()); } public static T CreateDbContext<T>(this DbConnection connection) where T : DbContext { var workspace = new MetadataWorkspace(new[] { "res://*/" }, new[] { typeof(T).Assembly }); var factory = DbProviderServices.GetProviderFactory(connection); var itemCollection = workspace.GetItemCollection(DataSpace.SSpace); var providerFactoryField = itemCollection.GetType().GetField("_providerFactory", PrivateInstance); if (providerFactoryField != null) providerFactoryField.SetValue(itemCollection, factory); var ec = new EntityConnection(workspace, connection); return CtorCache<T, DbConnection>.Ctor(ec); } public static DbConnection GetProfiledConnection<T>() where T : DbContext { var dbConnection = ObjectContextUtils.GetStoreConnection("name=" + typeof(T).Name); return new EFProfiledDbConnection(dbConnection, MiniProfiler.Current); } internal static class CtorCache<TType, TArg> where TType : class { public static readonly Func<TArg, TType> Ctor; static CtorCache() { var argTypes = new[] { typeof(TArg) }; var ctor = typeof(TType).GetConstructor(argTypes); if (ctor == null) { Ctor = x => { throw new InvalidOperationException("No suitable constructor defined"); }; } else { var dm = new DynamicMethod("ctor", typeof(TType), argTypes); var il = dm.GetILGenerator(); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Newobj, ctor); il.Emit(OpCodes.Ret); Ctor = (Func<TArg, TType>)dm.CreateDelegate(typeof(Func<TArg, TType>)); } } } }
It is based on code in MiniProfiler ObjectContextUtils
.
You use it as follows:
builder.Register(c => DbContextUtils.CreateDbContext<MyData>()).As<DbContext>().InstancePerHttpRequest();
This solution DbContext
your DbContext
in order to have a constructor that takes a DbConnection
and passes it to the base, for example:
public MyData(DbConnection connection) : base(connection, true) { }
khellang
source share