title: Re-instantiate a singleton with Prism in Xamarin Forms
body: <p>How can I dispose and re-instantiate a singleton with Prism/DryIoC in Xamarin Forms? </p>
  
  <p>I'm working with Azure Mobile Apps for offline data. Occasionally, I need to delete the local sqlite database and re-initialize it. Unfortunately the MobileServiceClient occasionally holds the db connection open and there's no method exposed to close it. The suggested solution (<a href="https://github.com/Azure/azure-mobile-apps-net-client/issues/379" rel="nofollow noreferrer">https://github.com/Azure/azure-mobile-apps-net-client/issues/379</a>) is to dispose of MobileServiceClient. Only problem is that is registered with DryIoC as a singleton.</p>
  
  <p>I'm not overly familiar with DryIoC, or Prism and Forms for that matter... But for the life of me, I can't see a way to do this.</p>
  
  <p>I did cook up a pretty elaborate scheme that almost worked. </p>
  
  <p>In my ViewModel method, when I needed the db freed up, I fired off an event -</p>
  
  <pre><code>_eventAggregator.GetEvent&lt;RegisterDatabaseEvent&gt;().Publish(false);
  </code></pre>
  
  <p>Then in App.xaml.cs, I wired up a listener and a handler like so -</p>
  
  <pre><code>_eventAggregator.GetEvent&lt;RegisterDatabaseEvent&gt;().Subscribe(OnRegisterDatabaseEventPublished);
  private void OnRegisterDatabaseEventPublished()
  {
      Container.GetContainer().Unregister&lt;IAppMobileClient&gt;();
      Container.GetContainer().Unregister&lt;IMobileServiceClient&gt;();
      Container.GetContainer().Register&lt;IMobileServiceClient, AppMobileClient&gt;(new SingletonReuse());
      Container.GetContainer().Register&lt;IAppMobileClient, AppMobileClient&gt;(new SingletonReuse());
  
      _eventAggregator.GetEvent&lt;RegisterDatabaseCompletedEvent&gt;().Publish(register);
  }
  </code></pre>
  
  <p>Lastly, back in the ViewModel constructor, I had a final listener that handled the event coming back from App.xaml and finished processing.</p>
  
  <pre><code>_eventAggregator.GetEvent&lt;RegisterDatabaseCompletedEvent&gt;().Subscribe(OnRegisterDatabaseCompletedEventPublished);
  </code></pre>
  
  <p>So the amazing thing is that this worked. The database was able to be deleted and all was good. But then I navigated to a different page and BOOM. DryIoC said it couldn't wire up the ViewModel for that page. I assume the unregister/register jacked up DryIoC for all injection... So how can I accomplish what needs to be done?</p>
  
  <p><strong>FINAL SOLUTION</strong></p>
  
  <p>Thanks so much to dadhi for taking the time to help. You are certainly a class act and I'm now considering using DryIoC elsewhere.</p>
  
  <p>For anyone who stumbles on this, I'm posting the final solution below. I'll be as verbose as I can to avoid any confusion.</p>
  
  <p>First, in my App.xaml.cs, I added a method for registering my database.</p>
  
  <pre><code>public void RegisterDatabase(IContainer container)
  {
      container.RegisterMany&lt;AppMobileClient&gt;(Reuse.Singleton,
          setup: Setup.With(asResolutionCall: true),
          ifAlreadyRegistered: IfAlreadyRegistered.Replace,
          serviceTypeCondition: type =&gt;
              type == typeof(IMobileServiceClient) || type == typeof(IAppMobileClient));
  }
  </code></pre>
  
  <p>I simply add a call to that method in RegisterTypes in place of registering the types in there directly.</p>
  
  <pre><code>protected override void RegisterTypes(IContainerRegistry containerRegistry)
  {
      containerRegistry.GetContainer().Rules.WithoutEagerCachingSingletonForFasterAccess();
  ...
      RegisterDatabase(containerRegistry.GetContainer());
  ...
  }
  </code></pre>
  
  <p>Note also the added rule for eager caching, per dadhi.</p>
  
  <p>Later on when I need to release the database in the ViewModel... I kick things off by resetting my local db variable and sending an event to App.xaml.cs</p>
  
  <pre><code>_client = null;
  _eventAggregator.GetEvent&lt;RegisterDatabaseEvent&gt;().Publish(true);
  </code></pre>
  
  <p>In App.xaml.cs, I have subscribed to that event and tied it to the following method.    </p>
  
  <pre><code>private void OnRegisterDatabaseEventPublished()
      {
          RegisterDatabase(Container.GetContainer());
  
          _eventAggregator.GetEvent&lt;RegisterDatabaseCompletedEvent&gt;().Publish(register);
      }
  </code></pre>
  
  <p>Here I just call RegisterMany again, exactly the same as I do when the app starts up. No need to unregister anything. With the setup and ifAlreadyRegistered arguments (thanks, dadhi!), DryIoC allows the object to be replaced. Then I raise an event back to the VM letting it know the database has been released.</p>
  
  <p>Finally, back in the ViewModel, I'm listening for the completed event. The handler for that event updates the local copy of the object like so.</p>
  
  <p><code>_client = ((PrismApplication)App.Current).Container.Resolve&lt;IAppMobileClient&gt;();</code></p>
  
  <p>And then I can work with the new object, as needed. This is key. Without setting _client to null above and resolving it again here, I actually ended up with 2 copies of the object and calls to methods were being hit 2x.</p>
  
  <p>Hope that helps someone else looking to release their Azure Mobile Apps database!</p>