Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- I don't know if I'm doing wrong, but I using DI to inject a global exception notifier to the appropriate target framework.
- I'm using Prism, and since Xamarin's `DependencyService` doesn't offer adding instances, I'm achieving this with reflection.
- So I've added this function that I call on the `RegisterTypes` of the portable app:
- public static class UnityContainerExtensions
- {
- public static void RegisterWithXamarin(this IUnityContainer container)
- {
- var depType = typeof(DependencyService);
- var depTypeInfo = depType.GetTypeInfo();
- depTypeInfo.DeclaredMethods.Single(mi => mi.Name == "Initialize").Invoke(null, null);
- var dependencyTypes = (List<Type>)depTypeInfo.DeclaredFields.Single(fi => fi.Name == "DependencyTypes").GetValue(null);
- if (dependencyTypes.Contains(depType))
- return;
- var targetType = typeof(IUnityContainer);
- var implementorType = container.GetType();
- dependencyTypes.Add(targetType);
- var nested = depTypeInfo.DeclaredNestedTypes.Single(t => t.Name == "DependencyData");
- var dependencyData = Activator.CreateInstance(nested.AsType());
- nested.DeclaredProperties.Single(p => p.Name == "ImplementorType").SetValue(dependencyData, implementorType);
- nested.DeclaredProperties.Single(p => p.Name == "GlobalInstance").SetValue(dependencyData, container);
- var dependencyImplementations = depTypeInfo.DeclaredFields.Single(fi => fi.Name == "DependencyImplementations").GetValue(null);
- dependencyImplementations.GetType().GetRuntimeProperty("Item").SetValue(dependencyImplementations, dependencyData, new[] { targetType });
- }
- }
- Now I'm adding another couple of classes to the portable app:
- public class GlobalExceptionHandler
- {
- public GlobalExceptionHandler(Action<GlobalExceptionData> handler)
- {
- ExceptionHandler = handler;
- }
- public void OnCompleted() { }
- public void OnError(Exception error) { }
- public void OnNext(GlobalExceptionData data) =>
- ExceptionHandler?.Invoke(data);
- public Action<GlobalExceptionData> ExceptionHandler { get; }
- }
- public class GlobalExceptionData
- {
- public GlobalExceptionData(Exception exception, bool handled = false, string message = null)
- {
- Exception = exception;
- Handled = handled;
- Message = message ?? exception.Message;
- }
- public Exception Exception { get; }
- public bool Handled { get; set; }
- public string Message { get; set; }
- }
- In the target-specific project I'm notifying the `GlobalExceptionHandler` (UWP in this example), _App.xaml.cs_ file:
- public App()
- {
- this.InitializeComponent();
- this.Suspending += OnSuspending;
- UnhandledException += App_UnhandledException;
- }
- private void App_UnhandledException(object sender, UnhandledExceptionEventArgs e)
- {
- var unityContainer = Xamarin.Forms.DependencyService.Get<IUnityContainer>();
- var exceptionHandler = unityContainer.Resolve<GlobalExceptionHandler>();
- var data = new GlobalExceptionData(e.Exception, e.Handled, e.Message);
- exceptionHandler.OnNext(data);
- e.Handled = data.Handled;
- }
- Make sure you call these two methods in the `RegisterTypes` method in the portable app:
- protected override void RegisterTypes()
- {
- Container.RegisterWithXamarin();
- Container.RegisterType<GlobalExceptionHandler>(new InjectionFactory(c => new GlobalExceptionHandler(OnGlobalException)));
- }
- Although this solution is prism specific it should be easy to adapt it to no-prism.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement