如何在简单注入器中构建 UnitOfWork 作用域对象图
How to Build a UnitOfWork Scoped Object Graph within Simple Injector
我们的网站目前正在使用 Ninject;然而,我们正在考虑转向 SimpleInjector(因为我们的测试显示速度提高了 26%)。但是,我们无法使 DbContext 的作用域正常工作。
这是我们工作单元模型的一个简单版本(shorthand):
class MyDbContext : EfDbContext, IStore, ICommitStorage
interface IRepoFactor
IRepoUnitOfWork CreateUnitOfWork();
class MyRepoUnitOfWork : RepoUnitOfWorkBase
MyRepoUnitOfWork(Container container, ICommitStorage dbContext)
: base(dbContext) {
_lazyLoadDto1= new Lazy<Dto1Repo>(container.GetInstance<Dto1Repo>);
_lazyLoadDto2= new Lazy<Dto2Repo>(containe.GetInstance<Dto2Repo>);
}
Dto1Repo Dto1 => _lazyLoadDto1.Value;
Dto2Repo Dto2 => _lazyLoadDto2.Value;
etc...
class Dto1Repo : Repository<Dto1>
Dto1Repo(IStore dbContext) {...}
class Dto2Repo : Repository<Dto2>
Dto2Repo(IStore dbContext) {...}
我们希望为 MyRepoUnitOfWork
创建的相同 MyDbContext
在 MyRepoUnitOfWork
class 拥有的所有存储库 class 之间共享。
目前我们的配置看起来像这样:
var container = new Container();
container.Options.DefaultScopedLifestyle = new AsyncScopedLifestyle();
container.Register<IRepoFactory, MyRepoFactory>();
container.Register<MyRepoUnitOfWork>(Lifestyle.Scoped);
var dbContextReg = Lifestyle.Scoped.CreateRegistration(() => new MyDbContext("(local)"), container);
container.AddRegistration<IStore>(dbContextReg);
container.AddRegistration<ICommitStorage>(dbContextReg);
总结
简而言之,我们想在 CreateUnitOfWork()
中创建一个 scope
,但要在 MyRepoUnitOfWork
对象中处理 scope
。类似于:
public MyRepoUnitOfWork CreateUnitOfWork(object args = null)
{
var scope = AsyncScopedLifestyle.BeginScope(_resolver);
return _resolver.GetInstance<MyRepoUnitOfWork>(scope);
}
但是我们不确定如何将作用域变量传递给 MyRepoUnitOfWork
对象。
有什么方法可以让它工作吗?或者有没有我们没有看到的 better/different 方法?
您可以使用 属性 注入代替:
public MyRepoUnitOfWork CreateUnitOfWork(object args = null)
{
var scope = AsyncScopedLifestyle.BeginScope(_resolver);
var uow = _resolver.GetInstance<MyRepoUnitOfWork>();
uow.Scope = scope;
return uow;
}
我们的网站目前正在使用 Ninject;然而,我们正在考虑转向 SimpleInjector(因为我们的测试显示速度提高了 26%)。但是,我们无法使 DbContext 的作用域正常工作。
这是我们工作单元模型的一个简单版本(shorthand):
class MyDbContext : EfDbContext, IStore, ICommitStorage
interface IRepoFactor
IRepoUnitOfWork CreateUnitOfWork();
class MyRepoUnitOfWork : RepoUnitOfWorkBase
MyRepoUnitOfWork(Container container, ICommitStorage dbContext)
: base(dbContext) {
_lazyLoadDto1= new Lazy<Dto1Repo>(container.GetInstance<Dto1Repo>);
_lazyLoadDto2= new Lazy<Dto2Repo>(containe.GetInstance<Dto2Repo>);
}
Dto1Repo Dto1 => _lazyLoadDto1.Value;
Dto2Repo Dto2 => _lazyLoadDto2.Value;
etc...
class Dto1Repo : Repository<Dto1>
Dto1Repo(IStore dbContext) {...}
class Dto2Repo : Repository<Dto2>
Dto2Repo(IStore dbContext) {...}
我们希望为 MyRepoUnitOfWork
创建的相同 MyDbContext
在 MyRepoUnitOfWork
class 拥有的所有存储库 class 之间共享。
目前我们的配置看起来像这样:
var container = new Container();
container.Options.DefaultScopedLifestyle = new AsyncScopedLifestyle();
container.Register<IRepoFactory, MyRepoFactory>();
container.Register<MyRepoUnitOfWork>(Lifestyle.Scoped);
var dbContextReg = Lifestyle.Scoped.CreateRegistration(() => new MyDbContext("(local)"), container);
container.AddRegistration<IStore>(dbContextReg);
container.AddRegistration<ICommitStorage>(dbContextReg);
总结
简而言之,我们想在 CreateUnitOfWork()
中创建一个 scope
,但要在 MyRepoUnitOfWork
对象中处理 scope
。类似于:
public MyRepoUnitOfWork CreateUnitOfWork(object args = null)
{
var scope = AsyncScopedLifestyle.BeginScope(_resolver);
return _resolver.GetInstance<MyRepoUnitOfWork>(scope);
}
但是我们不确定如何将作用域变量传递给 MyRepoUnitOfWork
对象。
有什么方法可以让它工作吗?或者有没有我们没有看到的 better/different 方法?
您可以使用 属性 注入代替:
public MyRepoUnitOfWork CreateUnitOfWork(object args = null)
{
var scope = AsyncScopedLifestyle.BeginScope(_resolver);
var uow = _resolver.GetInstance<MyRepoUnitOfWork>();
uow.Scope = scope;
return uow;
}