New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dialog Dependency Injection #938

Closed
wiltodelta opened this Issue Aug 8, 2016 · 3 comments

Comments

Projects
None yet
2 participants
@wiltodelta
Contributor

wiltodelta commented Aug 8, 2016

Hi!

I need an example with dependency injection in dialog constructor.
I have a service, that registers in Autofac container as singleton.

public class BotService : IBotService { }
public interface IBotService { }

builder.Register(c => new BotService())
    .As<IBotService>()
    .SingleInstance();

We pass a service to dialog constructor.

await Conversation.SendAsync(activity, () => new BotDialog(_botService));

public class BotDialog : IDialog
{
    private readonly IBotService _botService;

    public BotDialog(IBotService botService)
    {
        _botService = botService;
    }

    public async Task StartAsync(IDialogContext context)
    {
        context.Wait(MessageReceivedAsync);
    }

    public async Task MessageReceivedAsync(IDialogContext context, IAwaitable<IMessageActivity> argument)
    {
        IMessageActivity message = await argument;
        await context.PostAsync(string.Format("Message Received: {0}", message.Text));
        context.Wait(MessageReceivedAsync);
    }
 }

After each message I get an exception:

Exception: System.Runtime.Serialization.SerializationException: Type 'Abbyy.Contento.Bot.Web.Dialogs.BotDialog' in Assembly 'Abbyy.Contento.Bot.Web, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' is not marked as serializable

@willportnoy

This comment has been minimized.

Member

willportnoy commented Aug 8, 2016

Separate from dependency injection, the dialog should be marked as serializable.

For services, we use a keyed service in autofac to restore those services from the container rather than than the serialized blob. Here are some other options:

https://docs.botframework.com/en-us/technical-faq/#how-can-i-reference-non-serializable-services-from-my-c-dialogs

I have a sample in code review that uses Autofac and the ASP.NET DI hooks more extensively - hopefully I can publish that within a few days.

@willportnoy willportnoy self-assigned this Aug 8, 2016

@wiltodelta

This comment has been minimized.

Contributor

wiltodelta commented Aug 9, 2016

Thank you! Will wait for the example code. Now we use a workaround, but it doesn't seem good:

    [Serializable]
    public class BotDialog : IDialog
    {
        [NonSerialized]
        private BotService _botService;

        [OnDeserialized]
        private void onDeserialized(StreamingContext context)
        {
            _botService = (BotService) GlobalConfiguration.Configuration
                .DependencyResolver.GetService(typeof(BotService));
        }
@willportnoy

This comment has been minimized.

Member

willportnoy commented Aug 12, 2016

Here is the sample

https://github.com/Microsoft/BotBuilder/tree/develop/CSharp/Samples/AlarmBot

I'm going to close this issue, but feel free to open a new issue for further discussion.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment