gpt4 book ai didi

c# - DbContext 和作用域依赖

转载 作者:行者123 更新时间:2023-11-30 23:22:08 27 4
gpt4 key购买 nike

我有一个简单的 DbContext看起来像:

public class MyDbContext : DbContext
{
private readonly IUserContext _userContext;

public MyDbContext(IUserContext userContext) : base("DefaultConnectionString")
{
_userContext = userContext;

Database.SetInitializer(new MigrateDatabaseToLatestVersion<MyDbContext, Configuration>());
}

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
// ... Here I need to creates some filters using the IUserContext dependency

base.OnModelCreating(modelBuilder);
}

}

DbContext使用 Func<T> 接线工厂,using the guidelines in the Simple Injector documentation : container.RegisterFuncFactory<DbContext, MyDbContext>(Lifestyle.Scoped);

public static void RegisterFuncFactory<TService, TImpl>(
this Container container, Lifestyle lifestyle = null)
where TService : class
where TImpl : class, TService
{
lifestyle = lifestyle ?? Lifestyle.Transient;
var producer = lifestyle.CreateProducer<TService, TImpl>(container);
container.RegisterSingleton<Func<TService>>(producer.GetInstance);
}

但显然,DbContext 不可能实现这种简单的情况因为这个消息:

The target context 'MyDbContext' is not constructible. Add a default constructor or provide an implementation of IDbContextFactory.

我不太喜欢 IDbContextFactory 的想法, 所以我能想出的唯一解决方案是删除对 MyDbContext 的依赖,将其设置为属性,修改RegisterFuncFactory方法并手动初始化上下文:

internal static void RegisterFuncFactory<TService, TImpl>(this Container container, Func<TImpl> instanceProducer, Lifestyle lifestyle = null) where TService : class where TImpl : class, TService
{
lifestyle = lifestyle ?? Lifestyle.Transient;
var producer = lifestyle.CreateProducer<TService>(instanceProducer, container);
container.Register<Func<TService>>(() => producer.GetInstance, Lifestyle.Singleton);
}

container.RegisterFuncFactory<DbContext, MyDbContext>(() => new MyDbContext
{
UserContext = container.GetInstance<IUserContext>()
}, Lifestyle.Scoped);

虽然不优雅但它可以工作,但是否有另一种“更好”的方式来做我需要的事情?我喜欢明确地依赖于上下文,但似乎不可能。

更新

错误来自:

'System.Data.Entity.Migrations.Infrastructure.MigrationsException' occurred in EntityFramework.dll but was not handled in user code

在这段代码中,查询方法的返回语句在这里:

internal sealed class EntityFrameworkRepository<TEntity> : IEntityWriter<TEntity>, IEntityReader<TEntity> where TEntity : Entity
{
private readonly Func<DbContext> _contextProvider;

public EntityFrameworkRepository(Func<DbContext> contextProvider)
{
_contextProvider = contextProvider;
}

public IQueryable<TEntity> Query()
{
var context = _contextProvider();
return context.Set<TEntity>().AsNoTracking();
}

// Methods removed for brevity

}

最佳答案

添加第二个(默认)构造函数。这样,EF 迁移可以在从命令行运行时使用此构造函数,而您可以让您的应用程序使用第二个构造函数。

当您添加第二个构造函数时,您在 DbContext 上失去了 Simple Injector 的自动连接功能,但这应该不是问题;你可以简单地连接你的上下文如下:

IUserContext userContext = new AspNetUserContext();

container.RegisterSingleton<IUserContext>(userContext);

var contextProducer = Lifestyle.Scoped.CreateProducer<DbContext>(
() => new MyDbContext(userContext),
container);

container.RegisterSingleton<Func<DbContext>>(contextProducer.GetInstance);

关于c# - DbContext 和作用域依赖,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38911787/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com