2017-08-24 1 views
2

J'ai joué avec le framework bot, mais je me demandais juste si mon utilisation d'Autofac est correcte en utilisant context.Call(). Dois-je passer la décence du service de notation de RootDialog à ReviewDialog comme ceci (ci-dessous), ou y a-t-il un meilleur moyen?Bot Framework Autofac DI - Passer des dépendances lors de l'utilisation context.Call()

context.Call(new ReviewDialog(_ratingService), ChildDialogHasCompleted); 

MessagesController

[BotAuthentication] 
    public class MessagesController : ApiController 
    { 
     /// <summary> 
     /// POST: api/Messages 
     /// Receive a message from a user and reply to it 
     /// </summary> 
     public async Task<HttpResponseMessage> Post([FromBody]Activity activity) 
     { 
      if (activity.Type == ActivityTypes.Message) 
      { 
       using (var scope = DialogModule.BeginLifetimeScope(Conversation.Container, activity)) 
       { 
        await Conversation.SendAsync(activity,() => scope.Resolve<IDialog<object>>()); 
       } 
      } 

      var response = Request.CreateResponse(HttpStatusCode.OK); 
      return response; 
     } 
    } 

RootDialog

[Serializable] 
public class RootDialog : LuisDialog<object> 
{ 
    private IRatingService _ratingService; 

    public RootDialog(IRatingService ratingService) 
    { 
     this._ratingService = ratingService; 
    } 

    [LuisIntent("Movie")] 
    public async Task IntentSearch(IDialogContext context, LuisResult result) 
    { 
     // Do stuff 

     context.Call(new ReviewDialog(_ratingService), ChildDialogHasCompleted); 
    } 

    private async Task ChildDialogHasCompleted(IDialogContext context, IAwaitable<object> msg) 
    { 
     context.Done(true); 
    } 
} 

ReviewDialog

[Serializable] 
public class ReviewDialog : IDialog 
{ 
    private IRatingService _ratingService; 

    public ReviewDialog(IRatingService ratingService) 
    { 
     this._ratingService = ratingService; 
    } 

    public async Task StartAsync(IDialogContext context) 
    { 
     PromptDialog.Choice(context, ProcessRating, new List<string> { "1", "2", "3", "4", "5" }, "Please select your rating"); 
    } 

    public async Task ProcessRating(IDialogContext context, IAwaitable<string> msg) 
    { 
     var message = await msg; 

     context.UserData.TryGetValue("SelectedMovieId", out int movieId); 

     var rating = int.Parse(message); 

     _ratingService.Save(movieId, rating); 

     await context.PostAsync("Thank you"); 

     context.Done(true); 
    } 
} 

mondial

public class WebApiApplication : System.Web.HttpApplication 
{ 
    protected void Application_Start() 
    { 
     GlobalConfiguration.Configure(WebApiConfig.Register); 

     var builder = new ContainerBuilder(); 

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

     builder.RegisterType<RatingService>() 
       .Keyed<IRatingService>(FiberModule.Key_DoNotSerialize) 
       .AsImplementedInterfaces(); 

     builder.Update(Conversation.Container); 
    } 
} 

Toute aide serait grandement appréciée.

Répondre

2

La façon dont vous faites cela est totalement valable. Pour voir une autre implémentation veuillez vérifier AlarmBot

La façon dont vous faites ceci est généralement comment j'utilise DI dans les boîtes de dialogue. il y a une autre façon de passer des données/classes entre les boîtes de dialogue utilisant les sacs de données dans le contexte PrivateConversationData, ConversationData et UserData, mais il n'y a rien de mal dans la façon dont vous le faites