gpt4 book ai didi

entity-framework - 如何在 ServiceStack Core 中注册 DbContext EF Core?

转载 作者:行者123 更新时间:2023-12-02 02:56:42 25 4
gpt4 key购买 nike

在 EF Core 中,DbContext 被 EF 服务扩展注册为 Scoped。这是可取的,因为 DbContext 不是线程安全的,因此应该根据请求创建它。

ServiceStack IOC 将 Startup 中的任何 Scoped 注册视为单例,这与上述观点相矛盾。

一种可能的解决方案是不使用 EF Core 的服务扩展,但这似乎会带来大量样板代码并降低可维护性。有没有更好的办法?

--

更新

为了清楚起见,我想提供示例代码

我向 DbContext 类添加了一个私有(private) Guid,以便我可以判断我们是否拥有新实例。

public class BloggingContext : DbContext
{
private readonly Guid _instance;

public BloggingContext(DbContextOptions<BloggingContext> options)
: base(options)
{
_instance = Guid.NewGuid();
}

public DbSet<Blog> Blogs { get; set; }
}

使用 .NET Core MVC, Controller 代码看起来像

public class BlogsController : Controller
{
private readonly BloggingContext _context;

public BlogsController(BloggingContext context)
{
_context = context;
}

// skip for readability
}

对于每个到达 Controller 的请求,BloggingContext 中的 _instance 返回一个唯一值。但是,在 ServiceStack 服务中使用时,_instance 总是返回相同的值。

public class BlogService : ServiceStack.Service
{
private readonly BloggingContext _context;

public BlogService(BloggingContext context)
{
_context = context;
}

// skip for readability
}

此行为与有关 .NET Core Container Adapter 的 ServiceStack 文档一致在 .NET Core Startup 中注册的作用域依赖项在 ServiceStack 中是单例的。但是,这是不可取的,因为我们希望根据请求创建 DbContext。

我的解决方案是将 DbContext 注册移动到 AppHost 代码中,如下所示

public override void Configure(Container container)
{
container.AddScoped(c =>
{
var optionsBuilder = new DbContextOptionsBuilder<BloggingContext>();
optionsBuilder.UseSqlServer(connection);
return new BloggingContext(optionsBuilder.Options);
});
}

这段代码如我所料。注入(inject)我的 BlogService 的每个 BloggingContext 实例现在都是唯一的。但是,我发现自己无法再使用任何在 .Net Core Startup 中非常方便的服务集合扩展。例如,我想使用 Entity Framework Unit Of Work我不能调用

services
.AddUnitOfWork<BloggingContext>();

相反,我必须自己连接该库的所有依赖项

public override void Configure(Container container)
{
container.AddScoped(c =>
{
var optionsBuilder = new DbContextOptionsBuilder<BloggingContext>();
optionsBuilder.UseSqlServer(connection);
return new BloggingContext(optionsBuilder.Options);
});
container.AddScoped<IRepositoryFactory, UnitOfWork<BloggingContext>>();
container.AddScoped<IUnitOfWork, UnitOfWork<BloggingContext>>();
container.AddScoped<IUnitOfWork<BloggingContext>, UnitOfWork<BloggingContext>>();
}

最佳答案

您应该可以在 .NET Core's IOC 中注册它与任何 .NET Core 应用程序一样:

public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<BloggingContext>(options =>
options.UseSqlite("Data Source=blog.db"));
}

然后在您的 ServiceStack 服务中像普通依赖一样引用:

public class MyServices : Service
{
public BloggingContext BloggingContext { get; set; }
}

使用 ServiceStack's .NET Core Container Adapter在 .NET Core 的 IOC 中解决任何不在 ServiceStack 的 IOC 中的依赖项。

关于entity-framework - 如何在 ServiceStack Core 中注册 DbContext EF Core?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48987824/

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