locked
Getting different instances while resolving from container RRS feed

  • Question

  • User9811 posted

    I have a specific platform service which is being registered using a platform initializer

     public class AndroidInitializer : IPlatformInitializer
        {
            public void RegisterTypes(IContainerRegistry containerRegistry)
            {
                containerRegistry.RegisterInstance<IBlueToothService>(new BlueToothService_Android());
            }
        }
    

    As you see I am registering an instance as I want it to be the same instance. My main page VM get this service injected in its constructor:

    public MainPageViewModel(INavigationService navigationService, IBlueToothService btService)
               : base(navigationService)
            {
                 RefreshBlueTooothDevicesCommand = new DelegateCommand(RefreshBlueToothExecuted, RefreshBlueToothCanExecute);
                _blueToothService = btService;
                _blueToothService.DeviceAdded += BlueToothServiceDeviceAdded;
                _blueToothService.ScanFinished += () => ToggleRunningState();
            }
    

    I am using this service also in a broadcast receiver:

     public override void OnReceive(Context context, Intent intent)
            {            
               IBlueToothService service = Xamarin.Forms.DependencyService.Get<IBlueToothService>();
                string action = intent.Action;
                if (action == BluetoothDevice.ActionFound)
                {
                    BluetoothDevice newDevice = (BluetoothDevice)intent.GetParcelableExtra(BluetoothDevice.ExtraDevice);
                    service.AddDevice(new Models.BluetoothDevice(newDevice.Name, newDevice.Address));
                }
                if(action == BluetoothAdapter.ActionDiscoveryFinished)
                {
                    service.RaiseScanFinishedEvent();
                }
            }
    

    I am not getting the same instance. but 2 different ones. I am pretty sure that each one of them resolves them from a different container but I cant figure our how to point all of them to the same one.

    Thanks.

    Thursday, January 31, 2019 10:03 AM

Answers

  • User76049 posted

    @Balue said: @NMackay : This is exactly what I am trying to understand how can it be that the the android section has 1 instance and the shared generic section has a different one.

    I'd probably need a repo to assist but fully understand that it's not always possible.

    Don't forget the slack channel where the authors are always about (and are incredibly helpful), for edge cases like this they will very likely have suggestions

    https://prismlibrary.slack.com/

    Which IoC container are you using? I switched to DryIoC a while back, definitely quicker than Autofac & Unity

    • Marked as answer by Anonymous Thursday, June 3, 2021 12:00 AM
    Thursday, January 31, 2019 6:10 PM
  • User9811 posted

    so the problem was I as not acceding the right container. instead of:

    service = Xamarin.Forms.DependencyService.Get<IBlueToothService>();
    

    it should be

    var service = ((PrismApplication) Xamarin.Forms.Application.Current).Container.Resolve();
    

    you can see the full exmaple here: https://github.com/razamit/XamarinBlueToothExplorer

    Thanks! @NMackay

    • Marked as answer by Anonymous Thursday, June 3, 2021 12:00 AM
    Wednesday, February 6, 2019 10:09 AM

All replies

  • User76049 posted

    @Balue

    public class AndroidInitializer : IPlatformInitializer { public void RegisterTypes(IContainerRegistry containerRegistry) { containerRegistry.RegisterSingleton<IBlueToothService>(BlueToothService_Android()); } }

    Register your instance as a Singleton, otherwise the container will return you a fresh instance each time you inject it.

    Thursday, January 31, 2019 10:07 AM
  • User9811 posted

    Hey. What you wrote did not compile.

    I tried the following but still got the same result:

    public void RegisterTypes(IContainerRegistry containerRegistry)
            {
                //containerRegistry.RegisterInstance<IBlueToothService>(new BlueToothService_Android());
                containerRegistry.RegisterSingleton<IBlueToothService,BlueToothService_Android>();
            }
    

    it seems That containerRegistry.RegisterSingleton points to one container and IBlueToothService service = Xamarin.Forms.DependencyService.Get<IBlueToothService>(); points to a different one.

    Thursday, January 31, 2019 11:10 AM
  • User76049 posted

    @Balue said: Hey. What you wrote did not compile.

    I tried the following but still got the same result:

    public void RegisterTypes(IContainerRegistry containerRegistry)
            {
                //containerRegistry.RegisterInstance<IBlueToothService>(new BlueToothService_Android());
                containerRegistry.RegisterSingleton<IBlueToothService,BlueToothService_Android>();
            }
    

    it seems That containerRegistry.RegisterSingleton points to one container and IBlueToothService service = Xamarin.Forms.DependencyService.Get<IBlueToothService>(); points to a different one.

    Sounds like something is not set up right as we have some singleton platform specific services with no issues.

    Thursday, January 31, 2019 11:47 AM
  • User9811 posted

    @NMackay : This is exactly what I am trying to understand how can it be that the the android section has 1 instance and the shared generic section has a different one.

    Thursday, January 31, 2019 6:04 PM
  • User76049 posted

    @Balue said: @NMackay : This is exactly what I am trying to understand how can it be that the the android section has 1 instance and the shared generic section has a different one.

    I'd probably need a repo to assist but fully understand that it's not always possible.

    Don't forget the slack channel where the authors are always about (and are incredibly helpful), for edge cases like this they will very likely have suggestions

    https://prismlibrary.slack.com/

    Which IoC container are you using? I switched to DryIoC a while back, definitely quicker than Autofac & Unity

    • Marked as answer by Anonymous Thursday, June 3, 2021 12:00 AM
    Thursday, January 31, 2019 6:10 PM
  • User9811 posted

    @NMackay
    I used Unity. its quite a simple application. simply scans bluetooth devices around you

    I would gladly upload it to git if you could give it a look.

    Thursday, January 31, 2019 7:20 PM
  • User76049 posted

    @Balue said: @NMackay
    I used Unity. its quite a simple application. simply scans bluetooth devices around you

    I would gladly upload it to git if you could give it a look.

    Sure, DM me the link if you don't want to share it publicly.

    Thursday, January 31, 2019 7:27 PM
  • User9811 posted

    so the problem was I as not acceding the right container. instead of:

    service = Xamarin.Forms.DependencyService.Get<IBlueToothService>();
    

    it should be

    var service = ((PrismApplication) Xamarin.Forms.Application.Current).Container.Resolve();
    

    you can see the full exmaple here: https://github.com/razamit/XamarinBlueToothExplorer

    Thanks! @NMackay

    • Marked as answer by Anonymous Thursday, June 3, 2021 12:00 AM
    Wednesday, February 6, 2019 10:09 AM
  • User126884 posted

    @NMackay with Prism 7.2, has this changed? I want to register an instance for DI, in android both of the following seems to work, is one way better/correct than the other?

    public class AndroidInitializer : IPlatformInitializer
    {
        static OpenAppService openAppService = new OpenAppService();
    
        public void RegisterTypes(IContainerRegistry containerRegistry)
        {
            // Register any platform specific implementations
            containerRegistry.RegisterInstance<IOpenAppService>(openAppService);
    
            containerRegistry.Register<IFacebookLoginService, FacebookLoginService>();
        }
    }
    
    Sunday, March 22, 2020 5:43 AM