Как я могу заставить Prism сообщать об исключениях, в которые она попадает? - PullRequest
0 голосов
/ 24 января 2019

У меня есть приложение Prism WPF, которому не удалось загрузить один из его модулей при его развертывании (из-за проблемы с базой данных). На моей машине для разработки я вижу, как соответствующие исключения генерируются (и, очевидно, перехватываются и обрабатываются Prism) в окне вывода Visual Studio.

Я смог решить непосредственную проблему, выполнив следующее:

public MyModuleViewConstructor()
{
    try
    {
        // some startup work here
        // ...
        InitializeComponent();
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.ToString(), "A System Error Occurred.");
    }
}

Какая ошибка в производстве, чтобы я мог принять меры. Но я все еще хотел бы получать сообщения от любых исключений, которые выдают во время обычных операций, поэтому, в духе подхода Prism, я сделал это:

public class Logger : ILoggerFacade
{
    public void Log(string message, Category category, Priority priority)
    {
        using (StreamWriter s = File.AppendText("Log.txt"))
        {
            s.WriteLine(string.Format("{0}-{1}: {2}", DateTime.Now.ToString("MM/dd/yyyy HH:mm:ss.ffff"), priority.ToString(), message));
            s.Close();
        }
    }
}

И зарегистрировал его в Bootstrapper:

class Bootstrapper : DryIocBootstrapper
{
    private readonly Logger _logger = new Logger();

    protected override ILoggerFacade CreateLogger()
    {
        return _logger;
    }
}

Это прекрасно работает для обычных записей журнала, таких как ведение журнала отладки. Но он по-прежнему не регистрирует никаких исключений, выданных в моем приложении.

Как заставить Prism регистрировать выданные исключения в моем приложении?

Ответы [ 2 ]

0 голосов
/ 26 января 2019

При навигации все исключения, возникающие при просмотре и / или создании модели представления, перехватываются менеджером региона.Они не регистрируются по умолчанию (хотя это было бы крутой функцией).

Однако вы можете получить уведомление об исключении и зарегистрировать его самостоятельно или отреагировать иным образом.

Чтобы сделать это,переместиться через одну из IRegionManager.RequestNavigate( ..., Action<NavigationResult> navigationCallback ) перегрузок.navigationCallback будет передан объект результата, который содержит любое исключение в свойстве NavigationResult.Error.

0 голосов
/ 25 января 2019

Механизм регистрации Prism в основном используется для регистрации сообщений, связанных с событиями Prism. Чтобы использовать его для ваших событий, вы можете создать и расширить метод, например,

 public static class LoggerExtensions
    {
        public static void Warn(this ILoggerFacade loger, string message)
        {
            using (StreamWriter s = File.AppendText("Log.txt"))
            {
                s.WriteLine(string.Format(" {0}-{1}: {2}", DateTime.Now.ToString("MM/dd/yyyy HH:mm:ss.ffff"), Category.Warn, message));
                s.Close();
            }
        }
    }

И чтобы использовать его внутри своего кода, вы можете сделать следующее

  var logger = _container.Resolve<ILoggerFacade>(); //If you use IoC
  LoggerExtensions.Warn(logger, "Some exception...");

Но он по-прежнему не регистрирует исключения, выданные в моем приложении

Я бы предложил добавить Dispatcher.UnhandledException внутрь App.xaml.cs, поэтому, где бы ни было исключение, которое не было обработано, оно закончится там.

   public partial class App : Application
    {
        protected override void OnStartup(StartupEventArgs e)
        {
            base.OnStartup(e);
            this.Dispatcher.UnhandledException += OnDispatcherUnhandledException;
        }
        void OnDispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
        {
         //Your code
        }
    }

Обновление № 2 Я создал небольшой пример, где при нажатии кнопки выбрасывается DivideByZeroException. Механизм регистрации Prism вообще не знает об этом исключении. Единственное решение - использовать метод расширения, класс Exception или другие библиотеки. Я просто не вижу другого решения.

public partial class ViewA : UserControl
{
    ILoggerFacade logger;
    public ViewA(ILoggerFacade _logger)
    {
        InitializeComponent();
        logger = _logger;
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        try
        {
            var val = 0;
            var result = 1500 / val;
        }
        catch (Exception ex)
        {
            LoggerExtensions.Warn(logger, ex.Message);
        }

    }
}
...