Ejemplo n.º 1
0
        /// <summary>
        /// Process an incoming message within the conversation.
        /// </summary>
        /// <remarks>
        /// This method:
        /// 1. instantiates and composes the required components
        /// 2. deserializes the dialog state (the dialog stack and each dialog's state) from the <see cref="toBot"/> <see cref="Message"/>
        /// 3. resumes the conversation processes where the dialog suspended to wait for a <see cref="Message"/>
        /// 4. queues <see cref="Message"/>s to be sent to the user
        /// 5. serializes the updated dialog state in the messages to be sent to the user.
        ///
        /// The <see cref="MakeRoot"/> factory method is invoked for new conversations only,
        /// because existing conversations have the dialog stack and state serialized in the <see cref="Message"/> data.
        /// </remarks>
        /// <param name="toBot">The message sent to the bot.</param>
        /// <param name="MakeRoot">The factory method to make the root dialog.</param>
        /// <param name="token">The cancellation token.</param>
        /// <param name="singletons">An optional list of object instances that should not be serialized.</param>
        /// <returns>A task that represents the message to send inline back to the user.</returns>
        public static async Task <Message> SendAsync(Message toBot, Func <IDialog> MakeRoot, CancellationToken token = default(CancellationToken), params object[] singletons)
        {
            IWaitFactory     waits   = new WaitFactory();
            IFrameFactory    frames  = new FrameFactory(waits);
            IBotData         botData = new JObjectBotData(toBot);
            IConnectorClient client  = new ConnectorClient();
            var botToUser            = new ReactiveBotToUser(toBot, client);
            var provider             = new Serialization.SimpleServiceLocator(singletons)
            {
                waits, frames, botData, botToUser
            };
            var formatter = Conversation.MakeBinaryFormatter(provider);

            IDialogContextStore contextStore = new DialogContextStore(formatter);
            IDialogContextStore store        = new ErrorResilientDialogContextStore(contextStore);

            IDialogContext context;

            if (!store.TryLoad(botData.PerUserInConversationData, BlobKey, out context))
            {
                IFiberLoop fiber = new Fiber(frames);
                context = new Internals.DialogContext(botToUser, botData, fiber);
                var root = MakeRoot();
                var loop = root.Loop();
                context.Call <object>(loop, null);
                await fiber.PollAsync();
            }

            IUserToBot userToBot = (IUserToBot)context;
            await userToBot.SendAsync(toBot, token);

            store.Save(context, botData.PerUserInConversationData, BlobKey);

            return(botToUser.ToUser);
        }
Ejemplo n.º 2
0
        public async Task Fiber_Is_Serializable()
        {
            // arrange
            var waits  = new WaitFactory();
            var frames = new FrameFactory(waits);
            var fiber  = new Fiber(frames);

            // assert
            var previous = fiber;

            AssertSerializable(ref fiber, waits, frames);
            Assert.IsFalse(object.ReferenceEquals(previous, fiber));
            Assert.IsTrue(object.ReferenceEquals(previous.Factory, fiber.Factory));
        }