2016-08-07 12 views
8

का उपयोग कर मैं बहुत तरह MessagesController से एक LuisDialog के लिए एक सेवा पारित करने के लिए कोशिश कर रहा है:इंजेक्शन बाहरी निर्भरता Autofac

public async Task<HttpResponseMessage> Post([FromBody]Activity activity) 
... 
await Conversation.SendAsync(activity,() => new ActionDialog(botService)); 

botService निर्भरता इंजेक्शन का उपयोग कर MessageController में इंजेक्ट किया जाता।

जब मैं एक बॉट बातचीत शुरू मैं एक त्रुटि मिलती है:

प्रकार विधानसभा में 'ThetaBot.Services.BotService' 'ThetaBot.Services, संस्करण = 1.0.0.0, संस्कृति = तटस्थ, PublicKeyToken = अशक्त' नहीं है serializable के रूप में चिह्नित किया गया।

एक समाधान मैं पा सकते हैं के लिए चारों ओर देख रहे हैं: https://github.com/Microsoft/BotBuilder/issues/106

I understand your question better now. We have a similar issue with service objects that we want to instantiate from the container rather than from the serialized blob. Here is how we register those objects in the container - we apply special handling during deserialiation for all objects with the key Key_DoNotSerialize:

builder 
     .RegisterType<BotToUserQueue>() 
     .Keyed<IBotToUser>(FiberModule.Key_DoNotSerialize) 
     .AsSelf() 
     .As<IBotToUser>() 
     .SingleInstance(); 

हालांकि मैं एक उदाहरण या दस्तावेज मौजूदा बॉट फ्रेमवर्क मॉड्यूल में अपनी खुद की निर्भरता रजिस्टर करने के लिए कैसे का विवरण है कि नहीं मिल रहा।

मुझे https://github.com/Microsoft/BotBuilder/issues/252 भी मिला जो इंगित करता है कि कंटेनर से संवाद को तुरंत चालू करना संभव होना चाहिए। के साथ मिलकर

Func<IDialog<object>> makeRoot =() => actionDialog; 
await Conversation.SendAsync(activity, makeRoot); 

:

builder 
      .RegisterType<ActionDialog>() 
      .Keyed<ActionDialog>(FiberModule.Key_DoNotSerialize) 
      .AsSelf() 
      .As<ActionDialog>() 
      .SingleInstance(); 

यह काम नहीं करता

मैं इस सुझाव की कोशिश की है।

मैं भी कोशिश की है:

var builder = new ContainerBuilder(); 
builder.RegisterModule(new DialogModule_MakeRoot()); 

// My application module 
builder.RegisterModule(new ApplicationModule()); 

using (var container = builder.Build()) 
using (var scope = DialogModule.BeginLifetimeScope(container, activity)) 
{ 
    await Conversation.SendAsync(activity,() => scope.Resolve<ActionDialog>()); 
} 

साथ में ApplicationModule में निम्नलिखित के साथ:

  builder 
      .RegisterType<ActionDialog>() 
      .Keyed<ActionDialog>(FiberModule.Key_DoNotSerialize) 
      .AsSelf() 
      .As<ActionDialog>() 
      .SingleInstance(); 

यह काम नहीं करता और मैं एक ही समस्या आ।

यदि मैं बस सभी सेवाओं और उनकी निर्भरताओं को क्रमबद्ध करने के रूप में चिह्नित करता हूं तो मैं इसे फाइबर मॉड्यूल का उपयोग किए बिना काम करने के लिए प्राप्त कर सकता हूं। Key_DoNotSerialize।

सवाल यह है कि - पंजीकरण करने के लिए सही/पसंदीदा/अनुशंसित तरीका क्या है और बॉट फ्रेमवर्क संवाद में निर्भरता इंजेक्ट करें?

+0

मेरा मानना ​​है कि आपके पास गलत इंजेक्शन की वजह से अपवाद नहीं है, लेकिन आपके डायलॉग में 'ThetaBot.Services.BotService' प्रकार का एक गैर स्थैतिक क्षेत्र है। हालांकि उस प्रकार को धारावाहिक के रूप में चिह्नित नहीं किया गया है, लेकिन इसका उपयोग इस तरह से नहीं किया जा सकता है, स्वतंत्र रूप से अगर इसे इंजेक्शन दिया गया हो या नहीं। यदि आप अपनी निर्भरताओं के साथ सभी सेवाओं को क्रमबद्ध करने और संवाद स्थिति के साथ स्टोर करने के लिए अच्छे हैं, तो आपको 'FiberModule.Key_DoNotSerialize' का उपयोग करने की आवश्यकता नहीं है। दूसरे मामले में आप अपनी सेवाओं को किसी अन्य स्थान पर इंजेक्ट कर सकते हैं और वहां स्टोर किए बिना संवाद से उनका उपयोग कर सकते हैं। –

+0

हाय @ jim.taylor, क्या आपको इस समस्या के आसपास समाधान मिला। मैं फॉर्मफ्लो संवाद में सेवा पास करने की भी कोशिश कर रहा हूं। –

+1

@MurtazaTahirAli - मैंने अभी के लिए एक कामकाज का उपयोग किया। मैंने इंजेक्शन सेवा स्थिर बना दिया। [सीरियलज़ेबल] पब्लिक क्लास एक्शनडियलॉग: लुइसडियलॉग { निजी स्थैतिक आईबीओटी सेवा _botService; सार्वजनिक एक्शनडिअलॉग (आईबीओटीएस सर्विस बोट सेवा) { _botService = botService; } –

उत्तर

7

Global.asax.cs में, आप अपनी सेवाओं/संवाद रजिस्टर करने के लिए निम्न कार्य कर सकते हैं:

ContainerBuilder builder = new ContainerBuilder(); 

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

builder.RegisterType<JobsMapper>() 
    .Keyed<IMapper<DocumentSearchResult, GenericSearchResult>>(FiberModule.Key_DoNotSerialize) 
    .AsImplementedInterfaces() 
    .SingleInstance(); 

builder.RegisterType<AzureSearchClient>() 
    .Keyed<ISearchClient>(FiberModule.Key_DoNotSerialize) 
    .AsImplementedInterfaces() 
    .SingleInstance(); 

builder.Update(Conversation.Container); 

अपने नियंत्रक में, आप तो के रूप में अपने मुख्य संवाद को हल कर सकते हैं:

using (var scope = DialogModule.BeginLifetimeScope(Conversation.Container, activity)) 
{ 
    await Conversation.SendAsync(activity,() => scope.Resolve<IDialog<object>>()); 
} 
+0

अपडेट इन दिनों __Obselete__ है (कंटेनर को अपरिवर्तनीय, लार्डिडाडी माना जाता है), प्रतिस्थापन आशाजनक रूप से चल रहा है: https://github.com/Microsoft/BotBuilder/issues/1966 – flq

+2

प्रतिस्थापन का उपयोग करना है .UpdateContainer –

+0

उन लोगों के लिए अपडेटकॉन्टर का उपयोग करने के बारे में जानना चाहते हैं [ContosoFlower] पर नमूना देखें (https://github.com/Microsoft/BotBuilder-Samples/commit/09b58274fe9935de3c13660f4adf30d4ea3b2d77) –

संबंधित मुद्दे