我一直在阅读很多文章,解释如何设置实体框架,DbContext以便每个HTTP Web请求只使用各种DI框架创建和使用一个.
为什么这首先是一个好主意?使用这种方法有什么好处?在某些情况下这是个好主意吗?在使用DbContext存储库方法调用实例化s 时,您是否可以使用此技术执行某些操作?
我今天更新了一个项目到ASP.NET Core 2,我收到以下错误:
不能从singleton IActiveUsersService使用作用域服务IMongoDbContext
我有以下注册:
services.AddSingleton<IActiveUsersService, ActiveUsersService>();
services.AddScoped<IMongoDbContext, MongoDbContext>();
services.AddSingleton(option =>
{
var client = new MongoClient(MongoConnectionString.Settings);
return client.GetDatabase(MongoConnectionString.Database);
})
public class MongoDbContext : IMongoDbContext
{
private readonly IMongoDatabase _database;
public MongoDbContext(IMongoDatabase database)
{
_database = database;
}
public IMongoCollection<T> GetCollection<T>() where T : Entity, new()
{
return _database.GetCollection<T>(new T().CollectionName);
}
}
public class IActiveUsersService: ActiveUsersService
{
public IActiveUsersService(IMongoDbContext mongoDbContext)
{
...
}
}
Run Code Online (Sandbox Code Playgroud)
为什么DI无法使用该服务?一切都适用于ASP.NET Core 1.1.
在ASP.NET Core应用程序中,我可以像这样通过DI注册DbContext
services.AddDbContext<Models.ShellDbContext>(options => options.UseNpgsql(connection));
Run Code Online (Sandbox Code Playgroud)
而知道它的生命周期是什么呢?
从这里https://github.com/aspnet/EntityFramework/blob/f33b76c0a070d08a191d67c09650f52c26e34052/src/Microsoft.EntityFrameworkCore/EntityFrameworkServiceCollectionExtensions.cs#L140看起来它被配置为作用域,这意味着的DbContext实例在每次请求创建.
所以问题的第一部分是:它是真的,如果是,那么它的代价是多少?
第二部分是:如果我创建一个消耗DbContext的服务,并且打算由控制器使用,并且将有一个API来管理DB中的某些实体,它是否应该注册为Scoped?
我尝试使用存储库模式从我的数据库中获取数据我有 3 个项目
Bmu.Mode '这是用于创建数据库的模型'
Bmu.Repo '它有 2 个文件夹用于存储库,包括 contract/InewsRepository.cs' 和用于实现接口的 'Repository/NewsRepository'
Bmu.Api 用于从 Repo 项目调用数据
模型项目中的新闻类
namespace bmu.model
{
public class News
{
public int Id { get; set; }
public string SubTitle { get; set; }
public string Title { get; set; }
public string Summery { get; set; }
}
}
Run Code Online (Sandbox Code Playgroud)
模型项目中的上下文类
namespace bmu.model
{
public class BmuContext : DbContext
{
public BmuContext(DbContextOptions<BmuContext> options): base(options)
{
}
public DbSet<News> News { get; set; }
}
}
Run Code Online (Sandbox Code Playgroud)
我在 …
c# repository repository-pattern asp.net-core-mvc asp.net-core-3.0
我正在尝试解决 IoC 问题,一开始看起来很简单,但结果却很痛苦:-P
我有一个重量级主类,它必须只初始化一次,因此它被标记为单例。然而,该类使用一个必须为每个请求创建一次的子类,因此它被标记为 Transient:
public class MyRegistry : Registry
{
public MyRegistry()
{
For<IMainClass>()
.Singleton()
.Use(ctx => new MainClass(() => ctx.GetInstance<ISubClass>()));
For<ISubClass>()
.Transient()
.Use(ctx => CreateNewInstanceOfSubClass());
}
private ISubClass CreateNewInstanceOfSubClass()
{
return new SubClass();
}
}
public interface ISubClass
{ }
public class SubClass : ISubClass
{ }
public interface IMainClass
{ }
public class MainClass : IMainClass
{
private readonly Func<ISubClass> _subClassProvider;
public MainClass(Func<ISubClass> subClassProvider)
{
_subClassProvider = subClassProvider;
}
public void DoStuff()
{
var requestSpecificInstanceOfSubClass = _subClassProvider(); …Run Code Online (Sandbox Code Playgroud) 我实现了一个类EUMemberChecker,负责检查一个国家是否是欧盟成员。为了完成其工作,该类包含一个方法public bool IsEUMember(string country)。用于检查一个国家是否是欧盟成员的数据存储在 PostgreSQL 数据库表中。
我想通过 DI 将此类添加为单例服务,从而使其可用AddSingleton。原因是它应该只在应用程序启动时从数据库加载一次欧盟成员。如果我通过添加此类AddScoped,则它的每个实例都需要从数据库加载自己的欧盟成员列表,在我看来,这将是相当大的开销。
我的问题是我无法将此类添加为单例,因为它使用我的DbContext类作为范围服务添加。无论如何这样做,都会导致运行时错误Dependency ...DatabaseContext {ReturnDefault} as parameter "context" reuse CurrentScopeReuse {Lifespan=100} lifespan shorter than its parent's: singleton ... {ReturnDefault} as parameter ...。
因此,似乎我必须将我的类添加为范围服务,从而导致额外的数据库调用来为该类的每个实例加载欧盟成员国。
我在这里是否错误地应用了单一职责原则,或者如何解决这个问题?如何确保欧盟成员不会无故多次从数据库加载?
c# singleton dependency-injection single-responsibility-principle asp.net-core
c# ×5
asp.net-core ×3
asp.net ×1
dbcontext ×1
repository ×1
single-responsibility-principle ×1
singleton ×1
structuremap ×1