Пример #1
0
        public async Task Scorable_Where_Task()
        {
            foreach (var hasScore in new[] { false, true })
            {
                foreach (var whereScore in new[] { false, true })
                {
                    // arrange
                    IResolver resolver = new ArrayResolver(NullResolver.Instance, Item);
                    var       mock     = Mock(resolver, Score, Token, hasScore);
                    var       test     = mock.Object.Where(async(string item, double score) =>
                    {
                        Assert.AreEqual(Item, item);
                        Assert.AreEqual(Score, score);
                        return(whereScore);
                    });
                    // act
                    bool actualPost = await test.TryPostAsync(resolver, Token);

                    // assert
                    bool expectedPost = hasScore && whereScore;
                    Assert.AreEqual(expectedPost, actualPost);
                    Verify(mock, resolver, Token, Once(true), Once(true), Many(hasScore), Once(expectedPost));
                }
            }
        }
Пример #2
0
            protected override async Task <Token> PrepareAsync(IResolver innerItem, CancellationToken token)
            {
                var innerState = await this.scorable.PrepareAsync(innerItem, token);

                bool hasScore = false;

                if (this.scorable.HasScore(innerItem, innerState))
                {
                    var innerScore = this.scorable.GetScore(innerItem, innerState);
                    var outerItem  = new ArrayResolver(innerItem, innerScore);

                    IBinding <bool> binding;
                    if (Binder.Instance.TryBind <bool>(lambda, outerItem, out binding))
                    {
                        hasScore = await binding.InvokeAsync(token);
                    }
                }

                var state = new Token()
                {
                    Item     = innerItem,
                    Scorable = this.scorable,
                    State    = innerState,
                    HasScore = hasScore
                };

                return(state);
            }
Пример #3
0
        public static void Initialize(string[] assembliesNames = null, bool includeCommon = true)
        {
            if (_isInitialize)
            {
                return;
            }
            try
            {
                var collectionResolver = new ArrayResolver(CONTAINER.Kernel, true);
                CONTAINER.Kernel.Resolver.AddSubResolver(collectionResolver);

                var installersList = new List <IWindsorInstaller>();


                if (assembliesNames != null)
                {
                    installersList.AddRange(assembliesNames.Select(FromAssembly.Named));
                }

                CONTAINER.Install(installersList.ToArray());

                _isInitialize = true;
            }
            catch (FileLoadException)
            {
                throw;
            }
            catch (Exception exception)
            {
                throw new Exception("Failed to apply Castle Windsor installer from the assembly " + exception.Message, exception);
            }
        }
Пример #4
0
        protected virtual IResolver MakeResolver(IDialogContext context, IActivity activity)
        {
            var resolver = NoneResolver.Instance;

            resolver = new ArrayResolver(resolver, context, activity, this);
            resolver = new ActivityResolver(resolver);

            return(resolver);
        }
Пример #5
0
        protected virtual IResolver MakeResolver()
        {
            var services = this.MakeServices();
            var resolver = NoneResolver.Instance;

            resolver = new EnumResolver(resolver);
            resolver = new ArrayResolver(resolver, services);
            resolver = new ActivityResolver(resolver);
            resolver = new TriggerValueResolver(resolver);
            // TODO: add InvokeValueResolver

            return(resolver);
        }
Пример #6
0
        protected virtual IResolver MakeResolver()
        {
            var services = this.MakeServices();
            var resolver = NoneResolver.Instance;

            resolver = new EnumResolver(resolver);
            resolver = new ArrayResolver(resolver, services);
            resolver = new ActivityResolver(resolver);
            resolver = new EventActivityValueResolver(resolver);
            resolver = new InvokeActivityValueResolver(resolver);

            return(resolver);
        }
        /// <summary>
        /// Called during the chain of responsibility for a build operation. The
        /// PreBuildUp method is called when the chain is being executed in the
        /// forward direction.
        /// </summary>
        /// <param name="context">
        /// Context of the build operation.
        /// </param>
        public override void PreBuildUp(IBuilderContext context)
        {
            Type typeToBuild = context.BuildKey.Type;

            if (typeToBuild.IsArray && typeToBuild.GetArrayRank() == 1)
            {
                Type elementType = typeToBuild.GetElementType();

                MethodInfo resolverMethod = GenericResolveArrayMethod.MakeGenericMethod(elementType);

                ArrayResolver resolver = (ArrayResolver)Delegate.CreateDelegate(typeof(ArrayResolver), resolverMethod);

                context.Existing      = resolver(context);
                context.BuildComplete = true;
            }
        }
Пример #8
0
        public void Resolver_Array()
        {
            var expected = new Service();
            var resolver = new ArrayResolver(NullResolver.Instance, expected);

            {
                IService actual;
                Assert.IsTrue(resolver.TryResolve(null, out actual));
                Assert.IsFalse(resolver.TryResolve(Some, out actual));
            }

            {
                Service actual;
                Assert.IsTrue(resolver.TryResolve(null, out actual));
                Assert.IsFalse(resolver.TryResolve(Some, out actual));
            }
        }
Пример #9
0
        protected override void Load(ContainerBuilder builder)
        {
            base.Load(builder);

            builder.RegisterModule(new FiberModule <DialogTask>());

            // singleton components

            builder
            .Register(c => new ResourceManager("Microsoft.Bot.Builder.Resource.Resources", typeof(Resource.Resources).Assembly))
            .As <ResourceManager>()
            .SingleInstance();

            // every lifetime scope is driven by a message

            builder
            .Register((c, p) => p.TypedAs <IMessageActivity>())
            .AsSelf()
            .AsImplementedInterfaces()
            .InstancePerMatchingLifetimeScope(LifetimeScopeTag);

            // make the address and cookie available for the lifetime scope

            builder
            .Register(c => Address.FromActivity(c.Resolve <IActivity>()))
            .AsImplementedInterfaces()
            .InstancePerMatchingLifetimeScope(LifetimeScopeTag);

            builder
            .RegisterType <ResumptionCookie>()
            .AsSelf()
            .InstancePerMatchingLifetimeScope(LifetimeScopeTag);

            // components not marked as [Serializable]
            builder
            .RegisterType <MicrosoftAppCredentials>()
            .AsSelf()
            .SingleInstance();

            builder
            // not resolving IEqualityComparer<IAddress> from container because it's a very local policy
            // and yet too broad of an interface.  could explore using tags for registration overrides.
            .Register(c => new LocalMutualExclusion <IAddress>(new ConversationAddressComparer()))
            .As <IScope <IAddress> >()
            .SingleInstance();

            builder
            .Register(c => new ConnectorClientFactory(c.Resolve <IAddress>(), c.Resolve <MicrosoftAppCredentials>()))
            .As <IConnectorClientFactory>()
            .InstancePerLifetimeScope();

            builder
            .Register(c => c.Resolve <IConnectorClientFactory>().MakeConnectorClient())
            .As <IConnectorClient>()
            .InstancePerLifetimeScope();

            builder
            .Register(c => c.Resolve <IConnectorClientFactory>().MakeStateClient())
            .As <IStateClient>()
            .InstancePerLifetimeScope();

            builder
            .Register(c => new DetectChannelCapability(c.Resolve <IAddress>()))
            .As <IDetectChannelCapability>()
            .InstancePerLifetimeScope();

            builder
            .Register(c => c.Resolve <IDetectChannelCapability>().Detect())
            .As <IChannelCapability>()
            .InstancePerLifetimeScope();

            builder.RegisterType <ConnectorStore>()
            .AsSelf()
            .InstancePerLifetimeScope();

            // If bot wants to use InMemoryDataStore instead of
            // ConnectorStore, the below registration should be used
            // as the inner IBotDataStore for CachingBotDataStore

            /*builder.RegisterType<InMemoryDataStore>()
             *  .AsSelf()
             *  .SingleInstance(); */

            builder.Register(c => new CachingBotDataStore(c.Resolve <ConnectorStore>(),
                                                          CachingBotDataStoreConsistencyPolicy.ETagBasedConsistency))
            .As <IBotDataStore <BotData> >()
            .AsSelf()
            .InstancePerLifetimeScope();

            builder
            .RegisterType <JObjectBotData>()
            .AsSelf()
            .InstancePerLifetimeScope();

            builder
            .Register(c => new DialogTaskManagerBotDataLoader(c.Resolve <JObjectBotData>(),
                                                              c.Resolve <IDialogTaskManager>()))
            .As <IBotData>()
            .InstancePerLifetimeScope();

            builder
            .Register((c, p) => new BotDataBagStream(p.TypedAs <IBotDataBag>(), p.TypedAs <string>()))
            .As <Stream>()
            .InstancePerDependency();

            builder
            .Register(c => new DialogTaskManager(DialogModule.BlobKey,
                                                 c.Resolve <JObjectBotData>(),
                                                 c.Resolve <IStackStoreFactory <DialogTask> >(),
                                                 c.Resolve <Func <IDialogStack, CancellationToken, IDialogContext> >()))
            .AsSelf()
            .As <IDialogTaskManager>()
            .InstancePerLifetimeScope();

            builder
            .RegisterType <DialogContext>()
            .As <IDialogContext>()
            .InstancePerDependency();


            builder
            .Register(c =>
            {
                var cc = c.Resolve <IComponentContext>();

                Func <string, IBotDataBag, IStore <IFiberLoop <DialogTask> > > make = (taskId, botDataBag) =>
                {
                    var stream = cc.Resolve <Stream>(TypedParameter.From(botDataBag), TypedParameter.From(taskId));
                    return(cc.Resolve <IStore <IFiberLoop <DialogTask> > >(TypedParameter.From(stream)));
                };

                return(make);
            })
            .As <Func <string, IBotDataBag, IStore <IFiberLoop <DialogTask> > > >()
            .InstancePerDependency();


            builder.Register(c => c.Resolve <IDialogTaskManager>().DialogTasks[0])
            .As <IDialogStack>()
            .As <IDialogTask>()
            .InstancePerLifetimeScope();


            // Scorable implementing "/deleteprofile"
            builder
            .Register(c => new Regex("^(\\s)*/deleteprofile", RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace))
            .Keyed <Regex>(Key_DeleteProfile_Regex)
            .SingleInstance();

            builder
            .Register(c => new DeleteProfileScorable(c.Resolve <IDialogStack>(), c.Resolve <IBotData>(), c.Resolve <IBotToUser>(), c.ResolveKeyed <Regex>(Key_DeleteProfile_Regex)))
            .As <IScorable <IActivity, double> >()
            .InstancePerLifetimeScope();

            builder
            .Register(c =>
            {
                var cc = c.Resolve <IComponentContext>();
                Func <IActivity, IResolver> make = activity =>
                {
                    var resolver = NoneResolver.Instance;
                    resolver     = new EnumResolver(resolver);
                    resolver     = new AutofacResolver(cc, resolver);
                    resolver     = new ArrayResolver(resolver,
                                                     activity,
                                                     cc.Resolve <IDialogStack>(),
                                                     cc.Resolve <IBotToUser>(),
                                                     cc.Resolve <IBotData>(),
                                                     cc.Resolve <IDialogTaskManager>());
                    resolver = new ActivityResolver(resolver);
                    return(resolver);
                };
                return(make);
            })
            .AsSelf()
            .InstancePerLifetimeScope();

            builder
            .RegisterType <DialogRouter>()
            .Keyed <IScorable <IActivity, double> >(Key_Dialog_Router)
            .InstancePerLifetimeScope();

            builder
            .Register(c =>
            {
                var cc = c.Resolve <IComponentContext>();
                Func <IPostToBot> makeInner = () =>
                {
                    IPostToBot post = new ReactiveDialogTask(cc.Resolve <IDialogTask>(), cc.Resolve <Func <IDialog <object> > >());
                    post            = new ScoringDialogTask <double>(post, cc.ResolveKeyed <IScorable <IActivity, double> >(Key_Dialog_Router));
                    return(post);
                };

                IPostToBot outer = new PersistentDialogTask(makeInner, cc.Resolve <IBotData>());
                outer            = new SerializingDialogTask(outer, cc.Resolve <IAddress>(), c.Resolve <IScope <IAddress> >());
                outer            = new ExceptionTranslationDialogTask(outer);
                outer            = new LocalizedDialogTask(outer);
                outer            = new PostUnhandledExceptionToUserTask(outer, cc.Resolve <IBotToUser>(), cc.Resolve <ResourceManager>(), cc.Resolve <TraceListener>());
                outer            = new LogPostToBot(outer, cc.Resolve <IActivityLogger>());
                return(outer);
            })
            .As <IPostToBot>()
            .InstancePerLifetimeScope();

            builder
            .RegisterType <NullActivityLogger>()
            .AsImplementedInterfaces()
            .SingleInstance();

            builder
            .RegisterType <AlwaysSendDirect_BotToUser>()
            .AsSelf()
            .InstancePerLifetimeScope();

            builder
            .Register(c => new LogBotToUser(
                          new MapToChannelData_BotToUser(c.Resolve <AlwaysSendDirect_BotToUser>(), new [] { new KeyboardCardMapper() }),
                          c.Resolve <IActivityLogger>()))
            .As <IBotToUser>()
            .InstancePerLifetimeScope();
        }
Пример #10
0
        public override ResolveDelegate <PipelineContext>?Build(ref PipelineBuilder builder)
        {
            // Skip if already have a resolver
            if (null != builder.SeedMethod)
            {
                return(builder.Pipeline());
            }

            // Try to get resolver
            Type?generic  = null;
            var  resolver = builder.Policies?.Get(typeof(ResolveDelegate <PipelineContext>)) ??
                            builder.ContainerContext.Get(builder.Type, typeof(ResolveDelegate <PipelineContext>));

            if (null == resolver)
            {
#if NETCOREAPP1_0 || NETSTANDARD1_0
                if (null != builder.Type && builder.Type.GetTypeInfo().IsGenericType)
#else
                if (null != builder.Type && builder.Type.IsGenericType)
#endif
                {
                    generic  = builder.Type.GetGenericTypeDefinition();
                    resolver = builder.ContainerContext.Get(generic, typeof(ResolveDelegate <PipelineContext>));
                }
            }

            // Process if found
            if (null != resolver)
            {
                return(builder.Pipeline((ResolveDelegate <PipelineContext>)resolver));
            }

            // Try finding factory
            TypeFactoryDelegate?factory = builder.Policies?.Get <TypeFactoryDelegate>();

#if NETCOREAPP1_0 || NETSTANDARD1_0
            if (null != builder.Type && builder.Type.GetTypeInfo().IsGenericType)
#else
            if (null != builder.Type && builder.Type.IsGenericType)
#endif
            {
                factory = (TypeFactoryDelegate?)builder.ContainerContext.Get(builder.Type.GetGenericTypeDefinition(),
                                                                             typeof(TypeFactoryDelegate));
            }
            else if (null != builder.Type && builder.Type.IsArray)
            {
                if (builder.Type.GetArrayRank() == 1)
                {
                    var resolve = ArrayResolver.Factory(builder.Type, builder.ContainerContext.Container);
                    return(builder.Pipeline((ref PipelineContext context) => resolve(ref context)));
                }
                else
                {
                    var message = $"Invalid array {builder.Type}. Only arrays of rank 1 are supported";
                    return((ref PipelineContext context) => throw new InvalidRegistrationException(message));
                }
            }

            Debug.Assert(null != builder.Type);

            return(null != factory
                ? builder.Pipeline(factory(builder.Type, builder.ContainerContext.Container))
                : builder.Pipeline());
        }
        protected override void Load(ContainerBuilder builder)
        {
            base.Load(builder);

            builder.RegisterModule(new FiberModule <DialogTask>());

            // singleton components

            builder
            .Register(c => new ResourceManager("Microsoft.Bot.Builder.Resource.Resources", typeof(Resource.Resources).Assembly))
            .As <ResourceManager>()
            .SingleInstance();

            // every lifetime scope is driven by a message

            builder
            .Register((c, p) => p.TypedAs <IMessageActivity>())
            .AsSelf()
            .AsImplementedInterfaces()
            .InstancePerMatchingLifetimeScope(LifetimeScopeTag);

            // make the address and cookie available for the lifetime scope

            builder
            .Register(c => Address.FromActivity(c.Resolve <IActivity>()))
            .AsImplementedInterfaces()
            .InstancePerMatchingLifetimeScope(LifetimeScopeTag);

#pragma warning disable CS0618
            builder
            .RegisterType <ResumptionCookie>()
            .AsSelf()
            .InstancePerMatchingLifetimeScope(LifetimeScopeTag);
#pragma warning restore CS0618

            builder
            .Register(c => c.Resolve <IActivity>().ToConversationReference())
            .AsSelf()
            .InstancePerMatchingLifetimeScope(LifetimeScopeTag);

            // components not marked as [Serializable]
            builder
            .RegisterType <MicrosoftAppCredentials>()
            .AsSelf()
            .SingleInstance();

            builder
            // not resolving IEqualityComparer<IAddress> from container because it's a very local policy
            // and yet too broad of an interface.  could explore using tags for registration overrides.
            .Register(c => new LocalMutualExclusion <IAddress>(new ConversationAddressComparer()))
            .As <IScope <IAddress> >()
            .SingleInstance();

            builder
            .Register(c => new ConnectorClientFactory(c.Resolve <IAddress>(), c.Resolve <MicrosoftAppCredentials>()))
            .As <IConnectorClientFactory>()
            .ExternallyOwned();

            builder
            .Register(c => c.Resolve <IConnectorClientFactory>().MakeConnectorClient())
            .As <IConnectorClient>()
            .ExternallyOwned();

            builder
            .Register(c => c.Resolve <IConnectorClientFactory>().MakeStateClient())
            .As <IStateClient>()
            .ExternallyOwned();

            builder
            .RegisterType <ChannelCapability>()
            .AsImplementedInterfaces()
            .InstancePerLifetimeScope();

            builder
            .RegisterKeyedType <ConnectorStore, IBotDataStore <BotData> >()
            .InstancePerLifetimeScope();

            builder
            .RegisterKeyedType <InMemoryDataStore, IBotDataStore <BotData> >()
            .SingleInstance();

            builder
            .RegisterKeyedType <CachingBotDataStore, IBotDataStore <BotData> >()
            .WithParameter((pi, c) => pi.ParameterType == typeof(CachingBotDataStoreConsistencyPolicy),
                           (pi, c) => CachingBotDataStoreConsistencyPolicy.ETagBasedConsistency)
            .InstancePerLifetimeScope();

            builder
            .RegisterAdapterChain <IBotDataStore <BotData> >
            (
                typeof(ConnectorStore),
                typeof(CachingBotDataStore)
            )
            .InstancePerLifetimeScope();

            builder
            .RegisterKeyedType <JObjectBotData, IBotData>()
            .AsSelf()
            .InstancePerLifetimeScope();

            builder
            .RegisterKeyedType <DialogTaskManagerBotDataLoader, IBotData>()
            .InstancePerLifetimeScope();

            builder
            .RegisterAdapterChain <IBotData>
            (
                typeof(JObjectBotData),
                typeof(DialogTaskManagerBotDataLoader)
            )
            .InstancePerLifetimeScope();

            builder
            .Register((c, p) => new BotDataBagStream(p.TypedAs <IBotDataBag>(), p.TypedAs <string>()))
            .As <Stream>()
            .InstancePerDependency();

            builder
            .Register(c => new DialogTaskManager(DialogModule.BlobKey,
                                                 c.Resolve <JObjectBotData>(),
                                                 c.Resolve <IStackStoreFactory <DialogTask> >(),
                                                 c.Resolve <Func <IDialogStack, CancellationToken, IDialogContext> >(),
                                                 c.Resolve <IEventProducer <IActivity> >()))
            .AsSelf()
            .As <IDialogTaskManager>()
            .As <IDialogTasks>()
            .InstancePerLifetimeScope();

            builder
            .RegisterType <DialogSystem>()
            .As <IDialogSystem>();

            builder
            .RegisterType <DialogContext>()
            .As <IDialogContext>()
            .InstancePerDependency();

            builder
            .Register(c =>
            {
                var cc = c.Resolve <IComponentContext>();

                Func <string, IBotDataBag, IStore <IFiberLoop <DialogTask> > > make = (taskId, botDataBag) =>
                {
                    var stream = cc.Resolve <Stream>(TypedParameter.From(botDataBag), TypedParameter.From(taskId));
                    return(cc.Resolve <IStore <IFiberLoop <DialogTask> > >(TypedParameter.From(stream)));
                };

                return(make);
            })
            .As <Func <string, IBotDataBag, IStore <IFiberLoop <DialogTask> > > >()
            .InstancePerDependency();


            builder.Register(c => c.Resolve <IDialogTaskManager>().DialogTasks[0])
            .As <IDialogStack>()
            .As <IDialogTask>()
            .InstancePerLifetimeScope();

            // Scorable implementing "/deleteprofile"
            builder
            .Register(c => new Regex("^(\\s)*/deleteprofile", RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace))
            .Keyed <Regex>(Key_DeleteProfile_Regex)
            .SingleInstance();

            builder
            .Register(c => new DeleteProfileScorable(c.Resolve <IDialogStack>(), c.Resolve <IBotData>(), c.Resolve <IBotToUser>(), c.ResolveKeyed <Regex>(Key_DeleteProfile_Regex)))
            .As <IScorable <IActivity, double> >()
            .InstancePerLifetimeScope();

            // scorable implementing "end conversation"
            builder
            .RegisterInstance(EndConversationEvent.MakeScorable())
            .As <IScorable <IResolver, double> >()
            .SingleInstance();

            builder
            .Register(c =>
            {
                var cc = c.Resolve <IComponentContext>();
                Func <IActivity, IResolver> make = activity =>
                {
                    var resolver = NoneResolver.Instance;
                    resolver     = new EnumResolver(resolver);
                    resolver     = new AutofacResolver(cc, resolver);
                    resolver     = new ArrayResolver(resolver,
                                                     activity,
                                                     cc.Resolve <IBotToUser>(),
                                                     cc.Resolve <IBotData>(),
                                                     cc.Resolve <IDialogSystem>());
                    resolver = new ActivityResolver(resolver);
                    resolver = new EventActivityValueResolver(resolver);
                    resolver = new InvokeActivityValueResolver(resolver);
                    return(resolver);
                };
                return(make);
            })
            .AsSelf()
            .InstancePerLifetimeScope();

            builder
            .RegisterType <DialogRouter>()
            .Keyed <IScorable <IActivity, double> >(Key_Dialog_Router)
            .InstancePerLifetimeScope();

            builder
            .RegisterType <EventQueue <IActivity> >()
            .AsImplementedInterfaces()
            .InstancePerLifetimeScope();

            builder
            .RegisterType <ReactiveDialogTask>()
            .AsSelf()
            .InstancePerLifetimeScope();

            builder
            .Register(c => new ScoringEventLoop <double>(c.Resolve <ReactiveDialogTask>(), c.Resolve <ReactiveDialogTask>(), c.Resolve <IEventConsumer <IActivity> >(), c.ResolveKeyed <IScorable <IActivity, double> >(Key_Dialog_Router)))
            .As <IEventLoop>()
            .InstancePerLifetimeScope();

            // register IDataBag that is used for to load/save ResumptionData
            builder
            .Register(c =>
            {
                var cc = c.Resolve <IComponentContext>();
                Func <IBotDataBag> make = () =>
                {
                    return(cc.Resolve <IBotData>().PrivateConversationData);
                };
                return(make);
            })
            .As <Func <IBotDataBag> >()
            .InstancePerLifetimeScope();

            builder
            .RegisterType <ResumptionContext>()
            .AsSelf()
            .InstancePerLifetimeScope();

            builder
            .RegisterType <LocaleFinder>()
            .AsSelf()
            .AsImplementedInterfaces()
            .InstancePerLifetimeScope();

            // IPostToBot services

            builder
            .RegisterKeyedType <NullPostToBot, IPostToBot>()
            .SingleInstance();

            builder
            .RegisterKeyedType <PassPostToBot, IPostToBot>()
            .InstancePerDependency();

            builder
            .RegisterKeyedType <EventLoopDialogTask, IPostToBot>()
            .InstancePerLifetimeScope();

            builder
            .RegisterKeyedType <PersistentDialogTask, IPostToBot>()
            .InstancePerLifetimeScope();

            builder
            .RegisterKeyedType <ExceptionTranslationDialogTask, IPostToBot>()
            .InstancePerLifetimeScope();

            builder
            .RegisterKeyedType <SerializeByConversation, IPostToBot>()
            .InstancePerLifetimeScope();

            builder
            .RegisterKeyedType <SetAmbientThreadCulture, IPostToBot>()
            .InstancePerLifetimeScope();

            builder
            .RegisterKeyedType <PostUnhandledExceptionToUser, IPostToBot>()
            .InstancePerLifetimeScope();

            builder
            .RegisterKeyedType <LogPostToBot, IPostToBot>()
            .InstancePerLifetimeScope();

            builder
            .RegisterKeyedType <QueueDrainingDialogTask, IPostToBot>()
            .InstancePerLifetimeScope();

            builder
            .RegisterAdapterChain <IPostToBot>
            (
                typeof(EventLoopDialogTask),
                typeof(SetAmbientThreadCulture),
                typeof(QueueDrainingDialogTask),
                typeof(PersistentDialogTask),
                typeof(ExceptionTranslationDialogTask),
                typeof(SerializeByConversation),
                typeof(PostUnhandledExceptionToUser),
                typeof(LogPostToBot)
            )
            .InstancePerLifetimeScope();

            // other

            builder
            .RegisterType <NullActivityLogger>()
            .AsImplementedInterfaces()
            .SingleInstance();

            builder
            .RegisterType <KeyboardCardMapper>()
            .AsImplementedInterfaces()
            .SingleInstance();

            builder
            .RegisterType <SetLocalTimestampMapper>()
            .AsImplementedInterfaces()
            .SingleInstance();

            // IBotToUser services
            builder
            .RegisterType <InputHintQueue>()
            .AsImplementedInterfaces()
            .InstancePerLifetimeScope();

            builder
            .RegisterKeyedType <NullBotToUser, IBotToUser>()
            .SingleInstance();

            builder
            .RegisterKeyedType <PassBotToUser, IBotToUser>()
            .InstancePerDependency();

            builder
            .RegisterKeyedType <AlwaysSendDirect_BotToUser, IBotToUser>()
            .AsSelf()
            .InstancePerLifetimeScope();

            builder
            .RegisterKeyedType <AutoInputHint_BotToUser, IBotToUser>()
            .InstancePerLifetimeScope();

            builder
            .RegisterKeyedType <MapToChannelData_BotToUser, IBotToUser>()
            .InstancePerLifetimeScope();

            builder
            .RegisterKeyedType <LogBotToUser, IBotToUser>()
            .InstancePerLifetimeScope();

#pragma warning disable CS1587
            /// <see cref="LogBotToUser"/> is composed around <see cref="MapToChannelData_BotToUser"/> is composed around
            /// <see cref="AlwaysSendDirect_BotToUser"/>.  The complexity of registering each component is pushed to a separate
            /// registration method, and each of these components are replaceable without re-registering
            /// the entire adapter chain by registering a new component with the same component key.
#pragma warning restore CS1587
            builder
            .RegisterAdapterChain <IBotToUser>
            (
                typeof(AlwaysSendDirect_BotToUser),
                typeof(AutoInputHint_BotToUser),
                typeof(MapToChannelData_BotToUser),
                typeof(LogBotToUser)
            )
            .InstancePerLifetimeScope();
        }
 public OrderedArrayResolver(IKernel kernel, bool allowEmptyList)
 {
     innerArrayResolver = new ArrayResolver(kernel, allowEmptyList);
     sorter             = new Sorter();
 }