如何在简单注入器中构建 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 创建的相同 MyDbContextMyRepoUnitOfWork 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;
}