简体   繁体   中英

Autofac service not registered (Microsoft Bot Framework)

I am trying (in vain) to register my Dialog. My Dialog's constructor look like this:

// Private fields
protected readonly IGroupProvider _groupProvider;
protected readonly IProductProvider _productProvider;

protected IList<GroupResponseModel> _groups;
protected IList<ProductResponseModel> _products;

/// <summary>
/// Default constructor
/// </summary>
public PiiiCKDialog(IGroupProvider groupProvider, IProductProvider productProvider)
{
    SetField.NotNull(out this._groupProvider, nameof(groupProvider), groupProvider);
    SetField.NotNull(out this._productProvider, nameof(productProvider), productProvider);
}

In my PiiiCKModule , I have done this:

public class PiiiCKModule : Module
{
    protected override void Load(ContainerBuilder builder)
    {
        base.Load(builder);

        // Register our Luis Attribute
        builder.Register(c => new LuisModelAttribute("key", "key")).AsSelf().AsImplementedInterfaces().SingleInstance();

        // Register some singleton services
        builder.RegisterType<GroupProvider>().Keyed<IGroupProvider>(FiberModule.Key_DoNotSerialize).AsImplementedInterfaces().SingleInstance();
        builder.RegisterType<ProductProvider>().Keyed<IProductProvider>(FiberModule.Key_DoNotSerialize).AsImplementedInterfaces().SingleInstance();

        // Register the top level dialog
        builder.RegisterType<PiiiCKDialog>().As<LuisDialog<object>>().InstancePerDependency();
    }
}

And in my Global.ascx.cs file I have followed the Autofac quick start and created this:

public class WebApiApplication : HttpApplication
{
    protected void Application_Start(object sender, EventArgs e)
    {
        // Create our builder
        var builder = new ContainerBuilder();
        var config = GlobalConfiguration.Configuration;

        // Register the alarm dependencies
        builder.RegisterModule(new PiiiCKModule());

        // Register your Web API controllers.
        builder.RegisterApiControllers(Assembly.GetExecutingAssembly());

        // OPTIONAL: Register the Autofac filter provider.
        builder.RegisterWebApiFilterProvider(config);

        // Build.
        var container = builder.Build();

        // Set the dependency resolver to be Autofac.
        config.DependencyResolver = new AutofacWebApiDependencyResolver(container);

        // Configure our Web API
        GlobalConfiguration.Configure(WebApiConfig.Register);
    }

    public static ILifetimeScope FindContainer()
    {
        var config = GlobalConfiguration.Configuration;
        var resolver = (AutofacWebApiDependencyResolver)config.DependencyResolver;
        return resolver.Container;
    }
}

My controller looks like this:

[BotAuthentication]
public class MessagesController : ApiController
{
    // TODO: "service locator"
    private readonly ILifetimeScope scope;
    public MessagesController(ILifetimeScope scope)
    {
        SetField.NotNull(out this.scope, nameof(scope), scope);
    }

    /// <summary>
    /// POST: api/Messages
    /// Receive a message from a user and reply to it
    /// </summary>
    public async Task<HttpResponseMessage> Post([FromBody]Activity model, CancellationToken token)
    {

        // one of these will have an interface and process it
        switch (model.GetActivityType())
        {
            case ActivityTypes.Message:

                try

                {

                    // Create our conversation
                    await Conversation.SendAsync(model, () => scope.Resolve<PiiiCKDialog>());
                }
                catch (Exception ex)
                {

                }

                break;
            case ActivityTypes.ConversationUpdate:
            case ActivityTypes.ContactRelationUpdate:
            case ActivityTypes.Typing:
            case ActivityTypes.DeleteUserData:
            default:
                Trace.TraceError($"Unknown activity type ignored: { model.GetActivityType() }");
                break;
        }

        return new HttpResponseMessage(HttpStatusCode.Accepted);
    }
}

But when I run my application, I get this error:

'PiiiCKBot.Business.PiiiCKDialog' has not been registered. To avoid this exception, either register a component to provide the service, check for service registration using IsRegistered(), or use the ResolveOptional() method to resolve an optional dependency.

As far as I can tell, I am registering my component. Does anyone have any clue why this is not working?

Ok, I managed to get this to work:

First, in my Message controller I changed it to this:

await Conversation.SendAsync(model, () => scope.Resolve<IDialog<object>>());

It also appears that I have to add the [NonSerialized] attribute to the providers, which I was certain I wounldn't have to because of the Module where I do this:

builder.RegisterType<GroupProvider>().Keyed<IGroupProvider>(FiberModule.Key_DoNotSerialize).AsImplementedInterfaces().SingleInstance();

But it won't work without the data attribute. Finally, in my Module when I register the Dialog, it should be registered like this:

builder.RegisterType<PiiiCKDialog>().As<IDialog<object>>().InstancePerDependency();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM