Autofac 多重注册到单一服务。简单注入器 -> Autofac 翻译

Autofac Multiple Regsistrations to Single service. Simple Injector -> Autofac translation

我基于 Tripod 和其他灵感开发了一个 CQRS 风格的数据库访问框架,但针对 .NET Standard 并进行了简化以便于使用。我想将 IoC 拆分成单独的集成包,这样消费者就可以轻松地获得我目前在内部进行的类型注册,而不必被锁定在特定的 IoC 容器中。我的问题是我只真正与 SimpleInjector 密切合作,所以不熟悉其他系统以及它们在如何处理特定场景方面的细微差别。我迫切需要支持 Autofac,所以我想在这里试试看是否有人可以翻译。

我有以下静态简单注入器 CompositionRoot class:

public static void RegisterDatabase(this Container container, DbContextOptions<EntityDbContext> dbContextOptions, params Assembly[] assemblies)
{
    var scopedLifeStyle = container.Options.DefaultScopedLifestyle;

    //container.Register<ICreateDbModel, DefaultDbModelCreator>(scopedLifeStyle); // lifestyle c
    container.RegisterInitializer<EntityDbContext>( //(container.InjectProperties);
        handlerToInitialise => handlerToInitialise.ModelCreator = new DefaultDbModelCreator()
    );

    // Setup DbContext
    var ctxReg = scopedLifeStyle.CreateRegistration(
        () => new EntityDbContext(dbContextOptions),
        container);

    container.AddRegistration<IUnitOfWork>(ctxReg);
    container.AddRegistration<IReadEntities>(ctxReg);
    container.AddRegistration<IWriteEntities>(ctxReg);
}

在 ASP.NET 核心解决方案中,我从 Startup.Configure(...) 中调用上面的内容:

var optionsBuilder = new DbContextOptionsBuilder<EntityDbContext>()
    //.UseInMemoryDatabase("Snoogans");
    .UseSqlServer(_config.GetConnectionString("DefaultConnection"));
container.RegisterDatabase(optionsBuilder.Options);

这允许我在需要时切换到内存数据库进行单元测试。 EntityDbContext 包含我用于调用上下文的所有工作单元方法,而无需为每个 table 指定显式 DbSet。 IUnitOfWork、IReadEntities 和 IWriteEntities 接口都在 EntityDbContext 上定义方法。

所以我不确定我将如何制作一个 Autofac 模块,该模块允许通过传入的 DbContextOptions 对 dbcontext 进行范围注册,然后对这个注册的接口进行多次注册。

有人知道如何实现吗?

我制定了流程,现在有了一个 AutoFac 模块。我能够通过 class 的实例注册模块,并在实例化时传入选项。因为 EntityDbContext 实现了我在 Simple Injector 场景中分别注册的三个接口,AutoFac 可以方便地推断它们并使用 AsImplementedInterfaces()

注册
public class EntityFrameworkModule : Module
    {
        private readonly DbContextOptions<EntityDbContext> _dbContextOptions;

        public EntityFrameworkModule(DbContextOptions<EntityDbContext> dbContextOptions)
        {
            _dbContextOptions = dbContextOptions;

        }

        protected override void Load(ContainerBuilder builder)
        {
            // If the calling code hasn't already registered a custom 
            // ICreateDbModel then register the internal DefaultDbModelCreator
            builder.RegisterType<DefaultDbModelCreator>()
                .IfNotRegistered(typeof(ICreateDbModel))
                .As<ICreateDbModel>();

            // Expecting IUnitOfWork, IReadEntities and IWriteEntities to be registered with this call
            builder.Register(c => new EntityDbContext(_dbContextOptions)
                {
                    ModelCreator = c.Resolve<ICreateDbModel>()
                })
                .AsImplementedInterfaces()
                .InstancePerLifetimeScope();

        }
    }