botframework-sdk: FiberModule.Key_DoNotSerialize not working
Hi,
I have the following code in my Global.asax.cs:
protected void Application_Start()
{
GlobalConfiguration.Configure(WebApiConfig.Register);
var builder = new ContainerBuilder();
builder.RegisterType<AgendaSearchService>().Keyed<IAgendaSearchService>(FiberModule.Key_DoNotSerialize).AsImplementedInterfaces().SingleInstance();
builder.RegisterType<AgendaDialog>().As<IDialog<object>>().InstancePerDependency();
// Get your HttpConfiguration.
var config = GlobalConfiguration.Configuration;
// Register your Web API controllers.
builder.RegisterApiControllers(Assembly.GetExecutingAssembly());
// OPTIONAL: Register the Autofac filter provider.
builder.RegisterWebApiFilterProvider(config);
// Set the dependency resolver to be Autofac.
var container = builder.Build();
config.DependencyResolver = new AutofacWebApiDependencyResolver(container);
}
And my dialog is constructed like so:
{
[Serializable]
[LuisModel("modelId", "subscriptionId")]
public class AgendaDialog : LuisDialog<object>
{
private readonly IAgendaSearchService _searchService;
public AgendaDialog(IAgendaSearchService searchService)
{
SetField.NotNull(out _searchService, nameof(searchService), searchService);
}
But I still get the Type
‘Namespace.AgendaSearchService’ in Assembly ‘Bot Application1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null’ is not marked as serializable.
exception when trying to resolve the dependencies for my dialog.
My root dialog is resolved using an auto-factory in my controller:
private readonly Func<IDialog<object>> _makeRootFactory;
public MessagesController(Func<IDialog<object>> makeRootFactory)
{
_makeRootFactory = makeRootFactory;
}
Is there something that I am missing?
About this issue
- Original URL
- State: closed
- Created 8 years ago
- Comments: 29 (23 by maintainers)
My code didn’t work without that attribute, it was the whole point of raising the issue.
I’m confused as why I would want to use the serialization surrogate when I thought that the whole point of the
DoNotSerialize
key was to avoid having to do this in the first place.My understanding was that all I had to do was add
.Keyed<IAgendaSearchService>(FiberModule.Key_DoNotSerialize)
to my binding to allow my dependency to not be serialized but to be injected into the dialog but that doesn’t seem the case. That’s why I think I must be missing something.@grbinho you can do builder.Update(Conversation.Container) to override global registrations in there. It’s totally nonobvious how Autofac allows this, took me some time to figure out too. I use that now to register my (non serializable) services, so that I can resolve them inside Forms.
My guess is that it’s still trying to serialize the instance rather than ignore it and then recover it later.
I’ve had a brief look at the code and on serialization it does check if it has the Key_DoNotSerialize but it looks like it’s not being respected for whatever reason.
@willportnoy the issue that I originally raised was that marking a dialog that has non-serializable constructor parameters as serializable throws exceptions on serialisation when using FiberModule.Key_DoNotSerialize. Your solution doesn’t solve that problem. I still believe that this is a bug. I can provide more examples if necessary.
We have the same issue. Every service we tag with
FiberModule.Key_DoNotSerialize
is still being serialized.As far as I was able to tell, problem is that
Conversation
class creates a separate static container that registers onlyDialogModule
that in turn registersFiberModule
.FiberModule
has the code to enumerate all the services that are marked with that key. In this method. Because this is allstatic
and private, we are unable to add additional Autofact modules to it. Maybe there is an option to do something during runtime, but I’m not that familiar with Autofact.We worked around it by creating our own
Coversation
class, by basically copying the code and adding additional Autofact modules to the static constructor.