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.