Autofac 提供 func 来创建动态工厂

时间:2021-04-09 15:09:28

标签: c# dependency-injection autofac

我想在 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 类只是一个 Func 类的包装器,它提供了一种从 A 类到 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>>>();

1 个答案:

答案 0 :(得分:1)

您可以更改 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>>>();
    }
相关问题