luktom.net
  • blog
  • kontakt
  • english





Anatomia chatbota – część 7: IoC i serializacja

05 maj, 2017
Chatboty, Daj się poznać 2017
1 komentarz
Odsłony : 2761

W kolejnym wpisie z serii „Anatomia chatbota” zajmiemy się sprzątaniem naszego kodu oraz spróbujemy wprowadzić dependency injection.

Problem z DI oraz IoC w kontekście Bot Buildera jest taki, że – jak wspomniałem – dialogi są serializowane binarnie przez Bot Buildera. Niestety, nie wszystkie zależności, z których korzystamy są serializowalne lub też niekoniecznie chcemy je serializować. Oczywiście można je oznaczyć atrybutem NonSerialized i serializacja takiego dialogu się powiedzie, przy deserializacji jednak wylądujemy z jednym wielkim nullem :P

Rozwiązanie, które poniżej zaprezentuję nie jest idealne, gdyż bazuje ono na service locatorze (fuj!)… natomiast nic lepszego dotychczas nie wymyśliłem.

Zacznijmy od początku – używam Autofaca, więc przykłady bazują właśnie na nim. Instalujemy nugetowy pakiet Autofac.WebApi2:

Install-Package Autofac.WebApi2

W Global.asax, w metodzie Application_Start() tworzymy kontener IoC oraz ustawiamy domyślny dependency resolver na bazie tego kontenera:

var builder = new ContainerBuilder();

builder.RegisterApiControllers(Assembly.GetExecutingAssembly());
builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly());
builder.RegisterAssemblyTypes(BuildManager.GetReferencedAssemblies().Cast<Assembly>().ToArray());

var container = builder.Build();

GlobalConfiguration.Configuration.DependencyResolver = new AutofacWebApiDependencyResolver(container);

Mając powyższe ustawione, tworzymy dialog bazowy, który automatycznie będzie deserializował wszelkie zależności oznaczone atrybutem NonSerialized tuż po wykonaniu deserializacji, bazując na fakcie, że metoda oznaczona atrybutem OnDeserialized jest wywoływana każdorazowo po deserializacji binarnej:

[Serializable]
public abstract class AutoDeserializeDialog<T> : IDialog<T>
{
  [OnDeserialized]
  private void OnDeserialized(StreamingContext ctx)
  {
    foreach (FieldInfo field in obj.GetType().GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic))
    {
      if (field.GetCustomAttributes<NonSerializedAttribute>().Any<NonSerializedAttribute>())
        field.SetValue((object) obj, GlobalConfiguration.Configuration.DependencyResolver.GetService(field.FieldType));
    }
  }

  public abstract Task StartAsync(IDialogContext context);
  {
    // do nothing
  }
}

Teraz wystarczy jedynie utworzyć dialog z nieserializowalnymi zależnościami i dziedziczyć z AutoDeserializeDialog<T>, na przykład:

[Serializable]
public class FeedbackDialog : AutoDeserializeDialog<string>
{
  [NonSerialized]
  private readonly BotAccessor _accessor;

  public FeedbackDialog(BotAccessor accessor)
  {
    _accessor = accessor;
  }

  // .......
}

Powyższa klasa AutoDeserializeDialog<T> jest dostępna w mojej paczce nugetowej o nazwie Tomaszkiewicz.BotFramework.WebApi – wystarczy więc ją dodać do swojego projektu oraz uzupełnić rejestrację w Global.asax, i można korzystać z powyższego hacka na deserializację Bot Buildera :)

W następnych częściach…

… nie mam zaplanowanych kolejnych wpisów w ramach serii „Anatomia chatbota”. Planuję natomiast przejść do sztucznej inteligencji w zastosowaniach związanych z chatbotami, acz prawdopodobnie będzie to seria pod zupełnie nową nazwą – zobaczymy! :)

Aby nie przegapić kolejnych wpisów zapraszam do śledzenia tego bloga, czy to przez kanał RSS, czy też poprzez stronę na Facebooku.



Tagi :   bot builderbot frameworkchatbotydsp2017

Powiązane wpisy

  • SmogBot – wprowadzenie do projektu

  • Chatboty i sztuczna inteligencja – część 2: podstawy Wit.ai

  • Poznaj chatboty – startuję w „Daj się poznać 2017”

  • DSP2017 – organizacja repozytorium konkursowego

  • Komentarze ( 1 )

    • Wojtek maj 31 , 2017 at 16:32 /

      Witam
      A czy może próbowałeś podpiąć jakieś usługi LNP do takiego BOTa ?


    Dodaj komentarz

    Click here to cancel reply

    You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>





    Łukasz Tomaszkiewicz

    Łukasz Tomaszkiewicz

    Pasjonat chmury, szczególnie AWSa, który nieustannie automatyzuje powtarzające się czynności i optymalizuje procesy, przy okazji wdrażając dobre praktyki dotyczące bezpieczeństwa. Jego szerokie doświadczenie w zakresie tworzenia oprogramowania, projektowania baz danych, a także wirtualizacji serwerów i zarządzania infrastrukturą w chmurze pozwala mu spojrzeć przekrojowo na współczesny stack technologiczny.

    W wolnym czasie fotograf, sporadycznie piszący blogger :) a także regularny prelegent na krakowskich grupach związanych z IT.

    Wyznawca Vim'a :)

    Kategorie

    • Ansible
    • AWS
    • C#
    • Chatboty
    • Cloud
    • Daj się poznać 2017
    • Docker
    • Inne
    • Linux
    • Open source
    • Organizacyjne
    • Prelekcje
    • Sieci komputerowe
    • SQL Server
    • Windows
    • Windows Server
    • Wirtualizacja

    Najczęściej czytane

    • Creating single node VSAN cluster
    • SQL Server – walidacja numerów PESEL i NIP
    • Konfiguracja serwera DHCP na routerach Cisco
    • Aktywacja routingu IP w Windows 7 / Windows Server 2008
    • Konwersja maszyn wirtualnych z ESXi do Hyper-V przy użyciu SCVMM 2012
    • Jak podłączyć program R do SQL Servera?

    Tagi

    .net ai ansible asp.net mvc aws aws cli bot builder bot framework c# centos certyfikaty chatbot chatboty cisco cmd docker dsp2017 esxi hyperv kontenery konteneryzacja linux mvc nlp openvpn plssug pobieranie powershell prelekcje rancher redhat router sieci smogbot sql server ssd ssl vmware vsphere windows windows mobile windows server wirtualizacja wit.ai wrzuta

    Copyright © 2006-2018 by Łukasz Tomaszkiewicz. Wszelkie prawa zastrzeżone