You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Autofac如何注册集合与单个实例,使解析IEnumerable时包含所有IFoo实现

问题背景

众所周知,我们可以通过Autofac注册多个实例,解析时可获取到所有已注册的实现:

builder.RegisterType<Foo1>().As<IFoo>();    
builder.RegisterInstance(new Foo2("something")).As<IFoo>();    
builder.RegisterInstance(new Foo2("another")).As<IFoo>();

// 最终解析
var foos = ctx.Resolve<IEnumerable<IFoo>>();

目前我需要按如下方式注册部分IFoo实现:

builder.Register(ctx =>{
   var factory = ctx.Resolve<IFooFactory>();
   var allTheFoos = config.FooConfigs.Select(fooConfig => factory.CreateFoo(fooConfig));
   return allTheFoos;
}).As<IEnumerable<IFoo>>();

上述注册逻辑可以正常运行,但并非最优实现方式。如果再额外注册一个IFoo实例:

builder.RegisterInstance(new Foo2("this one")).As<IFoo>();    

此时解析IEnumerable<IFoo>时,仅能获取到显式注册为IEnumerable<IFoo>的集合,无法包含单独注册的Foo2("this one")实例:

// 仅包含allTheFoos,没有Foo2("this one")
var foos = ctx.Resolve<IEnumerable<IFoo>>();

由于业务设计原因,两部分注册逻辑位于不同模块中无法合并。需要将工厂生成的多个IFoo实例分别单独注册,且注册逻辑必须在可解析工厂的上下文内执行,期望可以实现类似如下的注册效果:

builder.Register(ctx => /* 生成foo实例 */).AsMultiple<IFoo>();

自定义注册源实现方案

以下是基于上述需求实现的自定义注册源示例代码:

public class BotRegistrationSource : IRegistrationSource
{
    private readonly IConfiguration _config;

    public BotRegistrationSource(IConfiguration config)
    {
        _config = config;
    }

    public IEnumerable<IComponentRegistration> RegistrationsFor(Service service,
        Func<Service, IEnumerable<ServiceRegistration>> registrationAccessor)
    {
        var swt = service as IServiceWithType;
        if (!(swt?.ServiceType.IsAssignableTo<IBot>() ?? false))
        {
            return Enumerable.Empty<IComponentRegistration>();
        }

        return  _config.GetSection("Bots")
            .GetChildren()
            .Select(c =>
                new ComponentRegistration(
                    Guid.NewGuid(),
                    new DelegateActivator(swt.ServiceType, (componentContext, _) =>
                    {
                        var botFactory = componentContext.Resolve<IBotFactory>();
                        var config = botFactory.CreateConfig();
                        c.Bind(config);
                        var bot = botFactory.Create(config);
                        bot.Enable();
                        return bot;
                    }),
                    new CurrentScopeLifetime(),
                    InstanceSharing.None,
                    InstanceOwnership.OwnedByLifetimeScope,
                    new[] { service },
                    new Dictionary<string, object>()));
    }

    public bool IsAdapterForIndividualComponents => false;
}

内容的提问来源于stack exchange,提问作者Stijn Van Antwerpen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 03:54:00