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
相关产品推荐
相关产品推荐

