首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将2个Autofac容器合并为一个

将2个Autofac容器合并为一个
EN

Stack Overflow用户
提问于 2015-10-19 09:01:38
回答 4查看 2.6K关注 0票数 2

有什么方法可以将2自动面容器合并成1吗?我的意思是,来自两个集装箱的所有注册都将包括在新的一个中,或者它可以升级其中一个与另一个。

例如:

代码语言:javascript
复制
public IContainer Merge(IContainer container1, IContainer container2)
{
     return ???;
}

我尝试过迭代"container.ComponentRegistry.Registrations“,并通过使用containerBuilder注册组件和升级第二个容器,但由于某些原因,存在一些冲突

代码语言:javascript
复制
    Autofac.Core.DependencyResolutionException : An exception was thrown while executing a resolve operation. See the InnerException for details. ---> The provided instance has already been used in an activation request. Did you combine a provided instance with non-root/single-instance lifetime/sharing? (See inner exception for details.)
  ----> System.InvalidOperationException : The provided instance has already been used in an activation request. Did you combine a provided instance with non-root/single-instance lifetime/sharing?
   at Autofac.Core.Resolving.ResolveOperation.Execute(IComponentRegistration registration, IEnumerable`1 parameters)
   at Autofac.Core.Lifetime.LifetimeScope.ResolveComponent(IComponentRegistration registration, IEnumerable`1 parameters)
   at Autofac.Core.Container.ResolveComponent(IComponentRegistration registration, IEnumerable`1 parameters)
   at Autofac.ResolutionExtensions.TryResolveService(IComponentContext context, Service service, IEnumerable`1 parameters, ref Object instance)
   at Autofac.ResolutionExtensions.ResolveService(IComponentContext context, Service service, IEnumerable`1 parameters)
   at Autofac.ResolutionExtensions.Resolve(IComponentContext context, Type serviceType, IEnumerable`1 parameters)
   at Autofac.ResolutionExtensions.Resolve(IComponentContext context, IEnumerable`1 parameters)
   at Autofac.ResolutionExtensions.Resolve(IComponentContext context)
   at Bootstrap.Bootstrapper.CreatePersistentTimerAsyncExecuter(IContainer container)
   at Bootstrap.Bootstrapper.Monitor(IContainer container)
   at Bootstrap.Bootstrapper.Boot(Assembly[] assemblies)
   at Soluto.Telemetry.Processing.Core.IntegrationTests.TelemetryProcessingBootstrapperTests.Boot_With2TelemetryHandlersInAssembly_ResolvesSubscriberWithItsHandlers() in TelemetryProcessingBootstrapperTests.cs: line 88
--InvalidOperationException
   at Autofac.Core.Activators.ProvidedInstance.ProvidedInstanceActivator.ActivateInstance(IComponentContext context, IEnumerable`1 parameters)
   at Autofac.Core.Resolving.InstanceLookup.Activate(IEnumerable`1 parameters)
   at Autofac.Core.Resolving.InstanceLookup.<Execute>b__0()
   at Autofac.Core.Lifetime.LifetimeScope.GetOrCreateAndShare(Guid id, Func`1 creator)
   at Autofac.Core.Resolving.InstanceLookup.Execute()
   at Autofac.Core.Resolving.ResolveOperation.GetOrCreateInstance(ISharingLifetimeScope currentOperationScope, IComponentRegistration registration, IEnumerable`1 parameters)
   at Autofac.Core.Resolving.ResolveOperation.ResolveComponent(IComponentRegistration registration, IEnumerable`1 parameters)
   at Autofac.Core.Resolving.ResolveOperation.Execute(IComponentRegistration registration, IEnumerable`1 parameters)

有什么想法吗?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2015-10-22 10:20:06

感谢所有的答案,伙计们,最终我做了一些更具体的事情来满足我的需要:

代码语言:javascript
复制
public void Merge(this IContainer container1, IContainer container2)
{ 
    var newBuilder = new ContainerBuilder();
    newBuilder.RegisterInstance(container2.Resolve<ISomeService1>()).AsImplementedInterfaces();
    newBuilder.RegisterInstance(container2.Resolve<ISomeService2>()).AsImplementedInterfaces();

    newBuilder.Update(container1);
    return container1;
}
票数 0
EN

Stack Overflow用户

发布于 2015-10-19 11:53:10

您可以使用自定义IRegistrationSource。此接口包含一个RegistrationsFor方法,该方法返回特定IServiceIComponentRegistration列表。

代码语言:javascript
复制
public class CrossContainerRegistrationSource : IRegistrationSource
{
    public CrossContainerRegistrationSource(IComponentContext componentContext)
    {
        this._componentContext = componentContext;
    }

    private readonly IComponentContext _componentContext;

    public Boolean IsAdapterForIndividualComponents
    {
        get
        {
            return false;
        }
    }

    public IEnumerable<IComponentRegistration> RegistrationsFor(Service service, 
        Func<Service, IEnumerable<IComponentRegistration>> registrationAccessor)
    {
        return this._componentContext.ComponentRegistry.RegistrationsFor(service);
    }
}

你可以这样使用它:

代码语言:javascript
复制
container2.ComponentRegistry.AddRegistrationSource(new CrossContainerRegistrationSource(container1));

但是,在使用复杂的范围场景时,请注意此解决方案可能会带来问题。

票数 2
EN

Stack Overflow用户

发布于 2015-10-19 09:28:16

是的是可能的。

代码语言:javascript
复制
var existingContainer = new ContainerBuilder();
// Add registrations to existing container.

var newContainerBuilder = new ContainerBuilder();
// Add registrations to new container.

newContainterBuilder.Update(existingContainer);

update方法本质上将existingContainer的内容合并到newContainerBuilder中。

编辑-如果使用IContainer

如果您已经将ContainerBuilder构建到IContainer中,则ContainerBuilderUpdate方法可以接受IContainer作为输入。但是在这种情况下,已经构建的容器现在将包含所有注册,新的ContainerBuilder可能超出范围。

代码语言:javascript
复制
var builtContainer = existingContainer.Build();

var newContainerBuilder = new ContainerBuilder();
// Add registrations to new container.

newContainterBuilder.Update(builtContainer);
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33210448

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档