При работе с WinForms получается куча обработчиков различных WinForms-событий.
Шаблон кода почти у всех одинаковый (см. ниже)
Есть ли хороший способ уйти от дублирования кода?
Здравствуйте, nikda, Вы писали:
N>При работе с WinForms получается куча обработчиков различных WinForms-событий. N>Шаблон кода почти у всех одинаковый (см. ниже) N>Есть ли хороший способ уйти от дублирования кода?
1. По возможности не бросать исключения для выдачи сообщений пользователю.
2. Навесить свою форму на Application.ThreadException event.
Здравствуйте, nikda, Вы писали:
N>При работе с WinForms получается куча обработчиков различных WinForms-событий. N>Шаблон кода почти у всех одинаковый (см. ниже) N>Есть ли хороший способ уйти от дублирования кода?
Здравствуйте, Sinix, Вы писали:
S>1. По возможности не бросать исключения для выдачи сообщений пользователю.
S>2. Навесить свою форму на Application.ThreadException event.
OK. Допустим нужно добавить в сообщение Exception дополнительную информацию, например:
"Открытие отчёта такого-то за такой-то период".
Можно сделать навесив атрибут на метод и в Application.ThreadException определить его по targetSite — но этот способ подходит только для статических строк.
А если нужно добавить более подробные данные, например очередной "шаг" в методе или введённые пользователем данные.
Exception можно получить, например при проверке данных, которые вернула база. И в итоге нужно увидеть на экране сообщение об ошибке:
"При Открытии отчёта такого-то за такой-то период база данных вернула ошибку такую-то"
Re[3]: [winforms][exception]Оформление оформление обработчиков событий
Здравствуйте, nikda, Вы писали:
N>"При Открытии отчёта такого-то за такой-то период база данных вернула ошибку такую-то"
Если есть желание извратиться с исключениями — чем nested exceptions не подходят?
Вызывающий код оформляем в
TryDo("SomeOpMessage", ()=>
{
// your code here
})
, работает
Re: [winforms][exception]Оформление оформление обработчиков событий
Здравствуйте, nikda, Вы писали:
N>При работе с WinForms получается куча обработчиков различных WinForms-событий. N>Шаблон кода почти у всех одинаковый (см. ниже) N>Есть ли хороший способ уйти от дублирования кода?
Перейти на шаблон проектирования UI MVP. Использовать View как источник первичной информации от пользователя, проводить нужные проверки через презентер в модели, при необходимости общаться через события.
Отображать информационные сообщения типа "Открытие отчёта такого-то за такой-то период" через исключения считаю не правильным. Но если очень хочется, то Sinix правильно подсказал
Здравствуйте, Sinix, Вы писали:
S>Здравствуйте, nikda, Вы писали:
N>>"При Открытии отчёта такого-то за такой-то период база данных вернула ошибку такую-то" S>Если есть желание извратиться с исключениями — чем nested exceptions не подходят?
S>Вызывающий код оформляем в S>
S>TryDo("SomeOpMessage", ()=>
S>{
S> // your code here
S>})
S>
, работает
1) Собственно так сейчас и есть. А необработанные исключения в — Application.ThreadException.
Но понравился вариант все обработать в Application.ThreadException, что бы не засорять код.
2) Понятно, что показывать пользователю технические/логические подробности ошибки не нужно (не обязательно).
Но в лог всё равно должно уйти подробное сообщение. Например, если получили от базы что-то не то или база вернула ошибку, нужно дополнить сообщение в логе не только самой ошибкой, но и например как до неё дошли: шаг в методе, ввод пользователя.
3) Или есть другой более правильный способ?
Re[2]: [winforms][exception]Оформление оформление обработчиков событий
Здравствуйте, Vasiliy2, Вы писали:
V>Здравствуйте, nikda, Вы писали:
N>>При работе с WinForms получается куча обработчиков различных WinForms-событий. N>>Шаблон кода почти у всех одинаковый (см. ниже) N>>Есть ли хороший способ уйти от дублирования кода?
V>Перейти на шаблон проектирования UI MVP. Использовать View как источник первичной информации от пользователя, проводить нужные проверки через презентер в модели, при необходимости общаться через события.
Просто код из формы перейдёт в презентер и там будут такие же обёртка try/catch для всех методов, реализующих реакцию на события от пользователя.
Re[3]: [winforms][exception]Оформление оформление обработчиков событий
N>Просто код из формы перейдёт в презентер и там будут такие же обёртка try/catch для всех методов, реализующих реакцию на события от пользователя.
Принципиально — да, согласен — простое перемещение просто идет из формы в презентер. Но здесь уже надо смотреть как вообще строить систему обработки исключений. Если она уже выстроена, то сильно не разгонишься.
Обрабатывать все в Application.ThreadException — я не уверен что это лучшая идея в плане того, что если исключение обработано не по месту, приложение может находится в несогласованном состоянии, когда некоторым данным уже доверять нельзя.
Есть вариант — выстроить систему обработки по слоям, например в модели обрабатывать нужные исключения и в PL пробрасывать событие. Здесь правда, при неправильной организации можно нарваться на то, что некоторые исключения могут быть случайно скрыты.
Re[4]: [winforms][exception]Оформление оформление обработчиков событий
Здравствуйте, Sinix, Вы писали:
S>Здравствуйте, nikda, Вы писали:
N>>"При Открытии отчёта такого-то за такой-то период база данных вернула ошибку такую-то" S>Если есть желание извратиться с исключениями — чем nested exceptions не подходят?
S>Вызывающий код оформляем в S>
S>TryDo("SomeOpMessage", ()=>
S>{
S> // your code here
S>)
S>
Ты или забыл зачем катч нужен — восстановить состояние UI из неконсистентного в консистентного.
Или просто прикалываешься?
В каждой операции и в общем случае действия для восстановления разные, и у топикстартера разные. так что оформлять тебе придется так:
S>
S>TryDo("SomeOpMessage", ()=>
S>{
S> // your code here
S>}, (exception)=>
S>{
S> // your recovery code here
S>})
S>
Re[5]: [winforms][exception]Оформление оформление обработчиков событий
Здравствуйте, VladCore, Вы писали:
VC>Или просто прикалываешься?
Не прикалываюсь, в подобных хелперах код по определению подразумевается атомарным (а в особо запущенных случаях с retry — ещё и идемпотентным), восстановление состояния — ответственность кода, а не собственно хелпера.
У нас за подобные штуки отвечает система локальных транзакций, т.е. откат работает автоматом. Без неё метод лучше бы обозвать как DoOperation();
Re[6]: [winforms][exception]Оформление оформление обработчиков событий
Здравствуйте, Sinix, Вы писали:
S>Здравствуйте, VladCore, Вы писали:
VC>>Или просто прикалываешься? S>Не прикалываюсь, в подобных хелперах код по определению подразумевается атомарным (а в особо запущенных случаях с retry — ещё и идемпотентным), восстановление состояния — ответственность кода, а не собственно хелпера.
Идемпотентность на UI? Нуну. Хотя вдруг пользователь вда раза кнопку нажал. Надо проверить
Re[7]: [winforms][exception]Оформление оформление обработчиков событий
Здравствуйте, VladCore, Вы писали:
VC>Идемпотентность на UI?
В бизлогике, топик читайте У топикстартера из кода формы выполняется "Открытие отчёта такого-то за такой-то период"...
Re[8]: [winforms][exception]Оформление оформление обработчиков событий
Здравствуйте, Sinix, Вы писали:
S>Здравствуйте, VladCore, Вы писали:
VC>>Идемпотентность на UI? S>В бизлогике, топик читайте У топикстартера из кода формы выполняется "Открытие отчёта такого-то за такой-то период"...