我正在使用 ASP.NET Core 及其内置 DI 容器。我正在使用无法更改的第三方库(NLog)。
My Foo
类具有依赖关系(通过构造函数注入)。
public class Foo {
private readonly IMyContext _context;
public Foo(IMyContext context) { _context = context; }
// etc.
}
然而该库缓存了Foo
实例在应用程序的持续时间内(这超出了我的控制范围)。这意味着它还缓存依赖项。并且该依赖项不得被缓存,因为它是一个应该限定范围的 EF 上下文。
另一种方法是注入IServiceProvider
,然后自己创建实例。
public class Foo {
private readonly IServiceProvider _sp;
public Foo(IServiceProvider sp) { _sp = sp; }
// etc.
public void bar() {
var context = _sp.GetService<IMyContext>();
// use it
}
}
但和之前一样,那IServiceProvider
实例将在应用程序的生命周期内被缓存。
这样“安全”吗?我应该了解哪些负面影响吗?
您不想将 IoC 容器注入到任何地方。这是一种不好的做法,它会导致草率的编码,并使单元测试变得更加困难,还有其他许多原因。
相反,引入一个可以注入的工厂并按需创建上下文:
public interface IDbContextFactory<TContext>
{
TContext Create();
}
public class DbContextFactory<TContext> : IDbContextFactory<TContext>
where TContext : DbContext
{
private readonly Func<TContext> _contextCreator;
public DbContextFactory(Func<TContext> contextCreator)
{
_contextCreator = contextCreator;
}
public TContext Create()
{
return _contextCreator();
}
}
现在如果你将其注入你的Foo
:
public class Foo
{
private readonly IDbContextFactory<MyContext> _contextFactory;
public Foo(IDbContextFactory<MyContext> contextFactory)
{
_contextFactory = contextFactory;
}
public void bar() {
{
using (var context = _contextFactory.Create())
{
// use your freshly instantiated context
}
}
}
任何像样的依赖注入框架都可以解决Func<TContext>
的参数DbContextFactory
,并传递一个 func 来为每个请求创建一个实例。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)