Autofac 提供创建动态工厂的功能

Autofac provide func to create dynamic factory

我想在 AutoFac 中创建一个动态工厂。让我概述一下我的问题,我正在尝试向我的工厂注册适配器:

注意:由于遗留代码,我无法修改内部适配器的架构。

protected void RegisterAdaptables(ContainerBuilder builder)
{
    this.RegisterAdaptableInstance
        <IOnboardingTask, OnboardingTaskDTO, IToDTOAdapterOptions<IOnboardingTask>>(
             builder,
             options => new OnboardingTaskGetterAdapter(options.Entity).ToDTO());
}

protected void RegisterAdaptableInstance<TEntity, TDTO, TOptions>(
    ContainerBuilder builder, Func<TOptions, TDTO> adaptFunc)
    where TOptions : IToDTOAdapterOptions<TEntity>
{
    var instance = new ToDTOAdaptable<TEntity, TDTO, TOptions>(adaptFunc);
    builder.RegisterInstance(instance)
        .As<IToDTOAdaptable<TEntity, TDTO, IToDTOAdapterOptions<TEntity>>>();
}

ToDTOAdaptable class 只是一个 Func 的包装器,它提供了一种从 class A 适应 class B 的方法,(注意: 这是这样做的,所以我们可以从我们的单例服务中实例化新的适配器)

有时我的内部适配器需要容器中提供的依赖项。

我想注册一个动态工厂,这样我就可以使用 注册 中的 IContainer

我希望能够注册一个 Adaptable,并从容器中获取额外的依赖项,例如

builder.RegisterFactory(IContainer container => { 
    return new ToDTOAdaptable(options => {
         var context = container.Resolve<MyDBContext>();
         return new OnboardingTaskGetterAdapter(context, options.Entity).ToDTO();
    });
}).As<IToDTOAdaptable<TEntity, TDTO, IToDTOAdapterOptions<TEntity>>>();

您可以更改 RegisterAdaptableInstance 方法以接受具有 autofac 组件上下文的 Func。然后,与其将实例注册到容器,不如注册一个函数,该函数将在它可以访问上下文的地方实例化它。

    protected void RegisterAdaptables(ContainerBuilder builder)
    {
        this.RegisterAdaptableInstance<IOnboardingTask, OnboardingTaskDTO, IToDTOAdapterOptions<IOnboardingTask>>(
                builder, 
                scope => 
                {
                    options =>
                    {
                        var context = scope.Resolve<MyDBContext>();
                        return new OnboardingTaskGetterAdapter(context, options.Entity).ToDTO();
                    }
                });
    }

    protected void RegisterAdaptableInstance<TEntity, TDTO, TOptions>(ContainerBuilder builder, Func<IComponentContext, Func<TOptions, TDTO>> getAdaptFunc)
        where TOptions : IToDTOAdapterOptions<TEntity>
    {
        builder
            .Register(c => new ToDTOAdaptable<TEntity, TDTO, TOptions>(getAdaptFunc(c)))
            .As<IToDTOAdaptable<TEntity, TDTO, IToDTOAdapterOptions<TEntity>>>();
    }