Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Autofac Dependency Injection works in Debug but crashes in Release

What would cause my DI to crash in Release mode when it's fine in Debug mode? This is a Xamarin.Forms app, and is being run on Android.

07-23 20:56:53.002 I/MonoDroid(15451): UNHANDLED EXCEPTION: Autofac.Core.DependencyResolutionException: An exception was thrown while executing a resolve operation. See the InnerException for details. ---> Object reference not set to an instance of an object (See inner exception for details.) ---> System.NullReferenceException: Object reference not set to an instance of an object
07-23 20:56:53.002 I/MonoDroid(15451):   at System.Linq.Expressions.Expression.CreateLambda (System.Type delegateType, System.Linq.Expressions.Expression body, System.String name, Boolean tailCall, System.Collections.ObjectModel.ReadOnlyCollection`1 parameters) [0x00000] in <filename unknown>:0 
07-23 20:56:53.002 I/MonoDroid(15451):   at System.Linq.Expressions.Expression.Lambda (System.Type delegateType, System.Linq.Expressions.Expression body, System.String name, Boolean tailCall, IEnumerable`1 parameters) [0x00000] in <filename unknown>:0 
07-23 20:56:53.002 I/MonoDroid(15451):   at System.Linq.Expressions.Expression.Lambda (System.Type delegateType, System.Linq.Expressions.Expression body, IEnumerable`1 parameters) [0x00000] in <filename unknown>:0 
07-23 20:56:53.002 I/MonoDroid(15451):   at Autofac.Features.GeneratedFactories.FactoryGenerator.CreateGenerator (System.Func`3 makeResolveCall, System.Type delegateType, ParameterMapping pm) [0x00000] in <filename unknown>:0 
07-23 20:56:53.002 I/MonoDroid(15451):   at Autofac.Features.GeneratedFactories.FactoryGenerator..ctor (System.Type delegateType, IComponentRegistration productRegistration, ParameterMapping parameterMapping) [0x00000] in <filename unknown>:0 
07-23 20:56:53.002 I/MonoDroid(15451):   at Autofac.Features.GeneratedFactories.GeneratedFactoryRegistrationSource+<>c__DisplayClass2.<RegistrationsFor>b__0 (IComponentRegistration r) [0x00000] in <filename unknown>:0 
07-23 20:56:53.002 I/MonoDroid(15451):   at System.Linq.Enumerable+<CreateSelectIterator>c__Iterator10`2[Autofac.Core.IComponentRegistration,Autofac.Core.IComponentRegistration].MoveNext () [0x00000] in <filename unknown>:0 
07-23 20:56:53.002 I/MonoDroid(15451):   at Autofac.Core.Registration.ComponentRegistry.GetInitializedServiceInfo (Autofac.Core.Service service) [0x00000] in <filename unknown>:0 
07-23 20:56:53.002 I/MonoDroid(15451):   at Autofac.Core.Registration.ComponentRegistry.TryGetRegistration (Autofac.Core.Service service, IComponentRegistration& registration) [0x00000] in <filename unknown>:0 
07-23 20:56:53.002 I/MonoDroid(15451):   at Autofac.Core.Activators.Reflection.AutowiringParameter.CanSupplyValue (System.Reflection.ParameterInfo pi, IComponentContext context, System.Func`1& valueProvider) [0x00000] in <filename unknown>:0 
07-23 20:56:53.002 I/MonoDroid(15451):   at Autofac.Core.Activators.Reflection.ConstructorParameterBinding..ctor (System.Reflection.ConstructorInfo ci, IEnumerable`1 availableParameters, IComponentContext context) [0x00000] in <filename unknown>:0 
07-23 20:56:53.002 I/MonoDroid(15451):   at Autofac.Core.Activators.Reflection.ReflectionActivator+<>c__DisplayClass5.<GetConstructorBindings>b__4 (System.Reflection.ConstructorInfo ci) [0x00000] in <filename unknown>:0 
07-23 20:56:53.002 I/MonoDroid(15451):   at System.Linq.Enumerable+<CreateSelectIterator>c__Iterator10`2[System.Reflection.ConstructorInfo,Autofac.Core.Activators.Reflection.ConstructorParameterBinding].MoveNext () [0x00000] in <filename unknown>:0 
07-23 20:56:53.002 I/MonoDroid(15451):   at System.Linq.Enumerable+<CreateWhereIterator>c__Iterator1E`1[Autofac.Core.Activators.Reflection.ConstructorParameterBinding].MoveNext () [0x00000] in <filename unknown>:0 
07-23 20:56:53.002 I/MonoDroid(15451):   at System.Linq.Enumerable.ToArray[ConstructorParameterBinding] (IEnumerable`1 source) [0x00000] in <filename unknown>:0 
07-23 20:56:53.002 I/MonoDroid(15451):   at Autofac.Core.Activators.Reflection.ReflectionActivator.ActivateInstance (IComponentContext context, IEnumerable`1 parameters) [0x00000] in <filename unknown>:0 
07-23 20:56:53.002 I/MonoDroid(15451):   at Autofac.Core.Resolving.InstanceLookup.Activate (IEnumerable`1 parameters) [0x00000] in <filename unknown>:0 
07-23 20:56:53.002 I/MonoDroid(15451):   at Autofac.Core.Resolving.InstanceLookup.Execute () [0x00000] in <filename unknown>:0 
07-23 20:56:53.002 I/MonoDroid(15451):   at Autofac.Core.Resolving.ResolveOperation.GetOrCreateInstance (ISharingLifetimeScope currentOperationScope, IComponentRegistration registration, IEnumerable`1 parameters) [0x00000] in <filename unknown>:0 
07-23 20:56:53.002 I/MonoDroid(15451):   at Autofac.Core.Resolving.ResolveOperation.ResolveComponent (IComponentRegistration registration, IEnumerable`1 parameters) [0x00000] in <filename unknown>:0 
07-23 20:56:53.002 I/MonoDroid(15451):   at Autofac.Core.Resolving.ResolveOperation.Execute (IComponentRegistration registration, IEnumerable`1 parameters) [0x00000] in <filename unknown>:0 
07-23 20:56:53.002 I/MonoDroid(15451):   -
Unhandled Exception:

Autofac.Core.DependencyResolutionException: An exception was thrown while executing a resolve operation. See the InnerException for details. ---> Object reference not set to an instance of an object (See inner exception for details.)

07-23 20:56:54.003 E/mono    (15451): 
07-23 20:56:54.003 E/mono    (15451): Unhandled Exception:
07-23 20:56:54.003 E/mono    (15451): Autofac.Core.DependencyResolutionException: An exception was thrown while executing a resolve operation. See the InnerException for details. ---> Object reference not set to an instance of an object (See inner exception for details.) ---> System.NullReferenceException: Object reference not set to an instance of an object
In mgmain JNI_OnLoad
07-23 20:56:54.003 E/mono    (15451):   at System.Linq.Expressions.Expression.CreateLambda (System.Type delegateType, System.Linq.Expressions.Expression body, System.String name, Boolean tailCall, System.Collections.ObjectModel.ReadOnlyCollection`1 parameters) [0x00000] in <filename unknown>:0 
07-23 20:56:54.003 E/mono    (15451):   at System.Linq.Expressions.Expression.Lambda (System.Type delegateType, System.Linq.Expressions.Expression body, System.String name, Boolean tailCall, IEnumerable`1 parameters) [0x00000] in <filename unknown>:0 
07-23 20:56:54.003 E/mono    (15451):   at System.Linq.Expressions.Expression.Lambda (System.Type delegateType, System.Linq.Expressions.Expression body, IEnumerable`1 parameters) [0x00000] in <filename unknown>:0 
07-23 20:56:54.003 E/mono    (15451):   at Autofac.Features.Generate
07-23 20:56:54.003 E/mono-rt (15451): [ERROR] FATAL UNHANDLED EXCEPTION: Autofac.Core.DependencyResolutionException: An exception was thrown while executing a resolve operation. See the InnerException for details. ---> Object reference not set to an instance of an object (See inner exception for details.) ---> System.NullReferenceException: Object reference not set to an instance of an object
07-23 20:56:54.003 E/mono-rt (15451):   at System.Linq.Expressions.Expression.CreateLambda (System.Type delegateType, System.Linq.Expressions.Expression body, System.String name, Boolean tailCall, System.Collections.ObjectModel.ReadOnlyCollection`1 parameters) [0x00000] in <filename unknown>:0 
07-23 20:56:54.003 E/mono-rt (15451):   at System.Linq.Expressions.Expression.Lambda (System.Type delegateType, System.Linq.Expressions.Expression body, System.String name, Boolean tailCall, IEnumerable`1 parameters) [0x00000] in <filename unknown>:0 
07-23 20:56:54.003 E/mono-rt (15451):   at System.Linq.Expressions.Expression.Lambda (System.Type delegateType, System.Linq.Expressions.Expression body, IEnumerable`1 parameters) [0x00000] in <filename unknown>:0 
07-23 20:56:54.003 E/mono-rt (15451):   at Autofac.Feat
The program 'Mono' has exited with code 0 (0x0).

An example of my constructor is this

    public MainPage(Func<Action, Action<bool?>, MainMenu> mainMenu, 
                    ModulePage modulePage, 
                    LoadingPage loadingPage, 
                    Func<Action, AuthPage> authPage,
                    IUserDialogService userDialogService, 
                    IModuleService moduleService, 
                    ISyncCommand syncCommand)
    {
        _loadingPage = loadingPage;
        _authPage = authPage;
        _userDialogService = userDialogService;
        _moduleService = moduleService;
        _syncCommand = syncCommand;

        Title = Strings.app_title;
        var master = mainMenu(OnAfterDeauthenticated, OnToggleRequest());
        var detail = new NavigationPage(modulePage);

        if (App.Navigation == null)
        {
            App.Navigation = detail.Navigation;
        }

        Master = master;
        Detail = detail;
    }

The ContainerBuilder gets initialized in the Android App, and then passed to the PCL.

Android

    protected override void OnCreate(Bundle bundle)
    {
        base.OnCreate(bundle);

        Forms.Init(this, bundle);

        var container = RegisterDependencies();
        var page = App.GetMainPage(container);

        SetPage(page);
    }

    private static IContainer RegisterDependencies()
    {
        var containerBuilder = new ContainerBuilder();
        RegisterAndroidSpecific(containerBuilder);

        var coreIoc = new CoreIoC(containerBuilder);
        return coreIoc.Load();
    }

    private static void RegisterAndroidSpecific(ContainerBuilder containerBuilder)
    {
        containerBuilder.RegisterType<AudioPlayer>().SingleInstance().As<IAudioPlayer>();
        containerBuilder.RegisterType<SettingsService>().As<ISettingsService>();
        containerBuilder.RegisterType<NetworkService>().As<INetworkService>();
        containerBuilder.RegisterType<NativeVideoPlayer>().As<IVideoPlayer>();
        containerBuilder.RegisterType<MarkdownService>().As<IMarkdownService>();
        containerBuilder.RegisterType<UserDialogService>().As<IUserDialogService>();

        containerBuilder.RegisterType<DbProvider>()
            .SingleInstance()
            .WithParameters(new List<Parameter> {
                new TypedParameter(typeof(string), "fsm-breathingroom"),
                new TypedParameter(typeof(SqliteSettings), new SqliteSettings {
                    CacheSize = 16777216,
                    SyncMode = SynchronizationModes.Off,
                    JournalMode = SQLiteJournalModeEnum.Off,
                    PageSize = 65536
                })
            })
            .As<IDbProvider>();
    }

PCL

    public static Page GetMainPage(IContainer container)
    {
        Container = container;

        RegisterCurrentUser(Container.Resolve<UserModel>());
        RunMigrations();
        RegisterCurrentUser();

        var rootPage = Container.Resolve<MainPage>();
        return rootPage;
    }
like image 432
Chase Florell Avatar asked Jul 24 '14 02:07

Chase Florell


People also ask

What is Autofac dependency injection?

Autofac is an addictive IoC container for . NET. It manages the dependencies between classes so that applications stay easy to change as they grow in size and complexity. This is achieved by treating regular . NET classes as components.

Why should I use Autofac?

AutoFac provides better integration for the ASP.NET MVC framework and is developed using Google code. AutoFac manages the dependencies of classes so that the application may be easy to change when it is scaled up in size and complexity.

What is Autofac core Dependencyresolutionexception?

Base exception type thrown whenever the dependency resolution process fails. This is a fatal exception, as Autofac is unable to 'roll back' changes to components that may have already been made during the operation.


1 Answers

This is a bug in the Mono Linker removing some code in System.Core, see https://bugzilla.xamarin.com/show_bug.cgi?id=22342 Xamarin claims it has been fixed in master in 11/2014, but I was not able to verify it yet. Should land with one of the next stable releases.

As a workaround, you can exclude System.Core from the linker Project->Options->Android Build->Linker->Ignore assemblies.

Alternatively, registering the Func directly works as well:

builder.Register<Func<FooPage>>(c => () => new FooPage());
like image 195
Johannes Rudolph Avatar answered Sep 20 '22 16:09

Johannes Rudolph