Что означает методика красивая обертка
Перейти к содержимому

Что означает методика красивая обертка

  • автор:

Часть III. Методика постижения

Вот перед вами находится книга, в которой описаны и разъяснены и государственная мудрость, и все пути развития личности и общества того времени. Это каббалистическая книга. Откройте ее, и вы найдете в ней описание всех добрых жизненных путей, которые раскроются в будущем, и получите хороший пример, чтобы уже сегодня в этом мире все расставить по своим местам.

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

Как ни странно, мировые реалии последних полутора веков во многом похожи на реалии времен Древнего Вавилона. За первой волной промышленной революции последовало ускоренное развитие во всех областях: энергетика и транспорт, телевидение и радио, киноиндустрия и биржа, предметы роскоши и пища для гурманов, хай-тек и демократия – все это бурно расцвело в последнее время. Эгоизм, впервые вырвавшийся наружу в Древнем Вавилоне, достиг заключительного этапа своего развития в начале XX столетия.

Все наши знания о духовных мирах мы получаем от каббалистов, которые эти миры постигли. Начертание букв в каббалистических текстах определяется соотношением духовных сил, свойственных определенной ступени. Таким образом, каббалисты создали алфавит языка иврит в виде 22 букв, с помощью которых можно во всех деталях изобразить картину, постигаемую человеком.

С раннего детства мы знаем, что такое книга. Первые сказки, прочитанные нам бабушкой про хорошего Иванушку и злого Кощея, мы проглатывали вместе с густой манной кашей. В школе нас научили читать, а также тому, что книги несут мудрое, вечное, доброе. О существовании книг не очень добрых и не очень мудрых мы узнали несколько позднее… Сегодня человечество открывает для себя особые книги, не похожие ни на какие другие. Это каббалистические книги. Еще не всем приходилось открывать эти книги, но зато все слышали, что в них содержится какой-то секрет. И верно, в них есть секрет. Но обо всем по порядку.

Если человек начинает спрашивать себя о цели жизни, не удовлетворяясь всевозможными психологическими игрушками и методиками, если религия не успокаивает его своими уговорами: «дескать, все будет хорошо», если он действительно ищет истину, если желает исследовать ее и судить о ней здраво и разумно, – тогда он приходит к каббале. Для тех, кто находится в ощущении этих сил, – для них это наука. Ну а для тех, кто еще не ощущает эти силы, это всего лишь умозрительная теория – может быть, интересная, но не более того.

Мечта любого ребенка – попасть в книгу приключений и стать ее главным героем. Как ни странно, духовный путь человека претворяет в жизнь забытую детскую мечту. Путь этот проходит через волшебные строки, за которыми проступает необъятный, необыкновенный мир.

Замысел книги «Зоар» (сияние) родился чуть менее двух тысячелетий назад в небольшой пещере неподалеку от поселения Пкиин в Западной Галилее. Там рабби Шимон Бар Йохай вместе с сыном рабби Эльазаром скрывались от преследования римлян. Ежедневно в течение тринадцати лет изучая науку каббала, они готовили себя к написанию книги, которой предстояло изменить судьбы человечества.

Испокон веков каббалисты искали возможность раскрыть человечеству методику достижения совершенства. Однако передача методики – дело сложное. Для этого нужно преодолеть множество препятствий.

Первая часть называется «тайны Торы», и их запрещено раскрывать, кому бы то ни было. Вторая часть называется «вкусы Торы», и раскрывать их можно всем. Более того, на раскрытие «вкусов Торы» не просто нет запрета – того, кто этим занимается, ждет огромное вознаграждение.

Глянул я вчера в календарь – вот те раз. Завтра Первое мая. Международный праздник трудящихся. Мой, значит, праздник. Сколько пота на производстве пролил. Пятый год на цементном заводе работаю, бухгалтером.

Решил – куплю себе подарок. Зашел в сувенирный магазин. Вижу, коробочка лежит резная, из красного дерева, а в ней домино из слоновой кости – мечта пенсионера. Класс! Глянул в ценник. Сразу о вечности вспомнил. И вообще, зачем мне домино? Да и до пенсии еще далеко…

Книга написана не для знания, не для запоминания. Читатель ни в коем случае не должен проверять себя, что же осталось у него в памяти от прочитанного. Хорошо, если все забывается, и повторно читаемый текст кажется абсолютно незнакомым. Это говорит о том, что человек полностью заполнил предыдущие чувства, и они отошли, предоставив место работе, заполнению новым, неизведанным чувствам. Процесс развития новых органов чувств постоянно обновляется и аккумулируется в духовной, неощущаемой сфере души.

Они хотели выделиться своей самобытностью, приподняться над суетой. Поначалу им казалось, что для этого нужны внешние отличия, но оба вовремя заметили, что даже красивая обертка не заменит подлинного внутреннего содержания. Миша Санилевич и Беня Карполов, плененные спортом, покоренные жаждой первенства, они нашли свободу в науке каббала.

Первый же вопрос «раскрутил» их с пол-оборота, и беседа сама устремилась вперед.

Я из тех, кто собирает книги в электронном формате. У меня вы не найдете корешков, которые годами тоскуют на пыльных полках. Моя библиотека раскинулась в виртуальном пространстве, многогранная, ухоженная и индексированная. Рукописи, фолианты, манускрипты, многотомные энциклопедии, словари неведомых языков, пособия, руководства, путеводители – короче говоря, неисчерпаемая сокровищница знаний, доступных по мановению «мыши».

Во всех каббалистических источниках, начиная с самых первых (например, книга «Сефер Ецира» была написана в Древнем Вавилоне, около четырех тысяч лет тому назад), говорится о том, что каббалу надо скрывать до тех пор, пока человечество не поймет: его безумное развитие в соответствии с эгоизмом, который постоянно растет в нас, – это совершенно неправильный путь.

© Материалы сайта предоставлены независимой, некоммерческой ассоциацией – Международной академией каббалы. Использование материалов сайта разрешается только при условии неизменности содержания и со ссылкой на соответствующую страницу материала.

По всем вопросам обращайтесь к администратору сайта.

Powered by Zapatec

  • Программа духовного развития
  • Основы Интегрального Общества
  • Внести Маасер
  • Новости
  • Курс «Схема мироздания»
  • Каббала обо всем
  • ВОСПРИЯТИЕ РЕАЛЬНОСТИ
  • Каббала и ее недруги
  • Сайт каббалиста М. Лайтмана
  • Что такое Каббала?
  • Библиотека
  • О нас
  • Каббала-медиа – архив записей
  • Связаться с нами
  • Каббала ТВ
  • Мир Каббалы
  • ЗНАКОМСТВО С КАББАЛОЙ
  • Изучение Каббалы
  • Каббала-ресурс
  • Обратная связь
  • Дистанционное обучение
  • Книжный магазин
  • Первоисточники
  • Курсы очного обучения
  • Блог каббалиста М. Лайтмана
  • КАББАЛА ДЛЯ ВСЕХ
  • Каббалистическая википедия
  • Кинокомпания Ari Films
  • Пожертвования
  • Книги для начинающих
  • Формы Изучения Каббалы
  • Уроки. Лекции. Курсы
  • Сайты-спутники
  • ЕЖЕДНЕВНЫЙ УРОК КАББАЛЫ
  • Самостоятельное изучение
  • Книга Зоар
  • Телепрограммы
  • ТВ
  • Курсы для начинающих
  • Основы Каббалы
  • Фильмы
  • Курс «Открываем Зоар»
  • Участие в распространении
  • Зоар ТВ. Смотреть бесплатно онлайн наше ТВ: клипы, фильмы, музыка!
  • Библиотека
    • Статьи ученых на тему «Каббала и наука»
    • Авраам
    • Михаэль Лайтман
    • Барух Ашлаг (РАБАШ)
    • Сборники РФО
    • Йегуда Ашлаг (Бааль Сулам)
    • Издания Академии каббалы
    • Творчество студентов
    • Другие авторы
    • АРИ
    • Притчи и примеры из каббалистических источников
    • Подростки хотят перемен
    • Каббалисты уполномочены сообщить
    • Школа для взрослых. Взгляд из будущего
    • Счастливое детство
    • Инструкция по выживанию в новом мире
    • Каббала – это очень просто
    • Каббалистический альманах №1
    • В поисках счастья
    • Путешествие в душу человека
    • Сборник трудов Бааль Сулама
    • Кризис – для нашего блага
    • Детские страхи
    • Психология интегрального сообщества
    • Развитие человека от 0 до 20
    • Человек – маленький мир
    • Полезные советы каббалиста
    • Предисловие
    • Редколлегия
    • От издателя
    • Примечание
    • Часть I. От замысла к действию
    • Часть II. Великие каббалисты
    • Вместо эпилога
    • Часть VI. Человечество
    • Часть V. Ступени духовного развития
    • Часть III. Методика постижения
    • Часть IV. Носители методики
    • Методика постижения
    • Глава 1. Носители духовной информации. Немного истории
    • Глава 1. Носители духовной информации. Вавилонская башня, последний ярус
    • Глава 1. Носители духовной информации. Контуры
    • Глава 1. Носители духовной информации. Секретное средство
    • Глава 1. Носители духовной информации. «Знание – сила»
    • Глава 2. Каббалистическая книга. Волшебный мир книги
    • Глава 2. Каббалистическая книга. Прикоснуться к «Зоар»
    • Глава 2. Каббалистическая книга. Тайны Торы
    • Глава 2. Каббалистическая книга. Эликсир жизни
    • Глава 3. Как это работает. Подарок
    • Глава 3. Как это работает. Постижение высших миров
    • Глава 3. Как это работает. Построй себя сам
    • Глава 3. Как это работает. Блог виртуального книгочея
    • Глава 3. Как это работает. Послесловие

    Что означает методика красивая обертка

    sid: 1135
    uid:
    request_id: PNm30NvZZiE1
    ip: 45.155.40.113
    datetime: 2023-10-30 09:23:25 +0000

    We are currently working on a lot of strange traffic.
    Sorry, we guessed you were a bot, please restart your browser.

    • Google Chrome
    • Safari
    • Yandex Browser
    • Other browsers

    Сейчас мы обрабатываем большое количество подозрительного трафика.
    Простите, мы подумали что вы робот, пожалуйста, перезапустите браузер.

    • Google Chrome
    • Safari
    • Yandex Browser
    • Другой браузер

    Наразі ми обробляємо багато підозрілого трафіку.
    Вибачте, ми подумали, що ви робот, будь ласка, перезапустіть браузер.

    • Google Chrome
    • Safari
    • Yandex Browser
    • Інший браузер

    Красивая обертка для try-catch в C#

    Вопрос не про то, как красиво программировать, чтобы этот вопрос не возникал, а про красивую обертку над try-catch .

    try < >catch < // здесь ничего нет >
    • эта хорошая штука, но но занимает много места, хотелось бы, чтобы умещалось в один блок, но выполняло тот же функционал

    Делаю кусок кода, который подстраховочный и вообще не достоин, чтобы на него уделяли большое внимание (сейчас уделяю такое внимание только на будущее, потому, что уже не раз задумывался над этой issue, ну и чтоб отдохнуть). Он не стоит того, чтобы делать рефакторинг, чтоб изящничать. Нужно просто и быстро поставить try , но хотелось бы чтобы это выглядело красиво. Если там что-то не сработает, то ничего страшного, но хотелось бы еще, чтобы это не повлекло за собой появление Exception-а уже в важных местах, поэтому вопрос про try-catch .

    Есть вариант сделать метод:

    private void Try(Action codeBlock) < try < codeBlock?.Invoke(); >catch < >> 

    тогда вызов будет в одну строчку, но этот вариант не на 100% нравится:

    • кажется не красивым вызов Try( ()=>DoWork() ); , хотелось бы что-то попроще, без наворотов
    • можно в аргумент передать вызов метода напрямую Try(MethodCall) , это уже выглядит получше, но тогда в моем конкретном случае придется разбивать этот подстраховочный и второстепенный по важности метод на многие части, например, если случай такой:

    private static void EnsureSomethingWhichFailsAnyway(Someting input) < try < foreach (var x in input.GetAllX()) < DoSmallThing(x); try < x.SetPropertyValue = PossibleValues.BigValue; >catch < >> > catch < >try < foreach (var y in input.GetllY()) < try < y.Validate(StaticVars.A, StaticVars.B, StaticVars.C); >catch < >> > catch < >> 

    Отслеживать
    задан 20 июн 2019 в 12:46
    1,254 7 7 серебряных знаков 26 26 бронзовых знаков

    Тихие исключения опасно использовать, потому что. в итоге очень сложно отыскать ошибку. Хорошо бы вернуть и обработать хотя бы boolean. Какая у вас цель на самом деле?

    20 июн 2019 в 12:52

    @nick_n_a, спасибо, полезно! Но в моем случае вопрос про то, когда код такой что не на что по сути не влияет.

    20 июн 2019 в 12:59

    Я так и не понял, чем плох способ, который вы предлагаете (блок try поместить в метод Try , в который передается делегат).

    20 июн 2019 в 13:06

    @AndreiKhotko, спасибо! — тут дело такое, что сам метод внутри разбит на try-catch на каждый чих. Разбивать на подметоды — игра не стоит свеч.

    20 июн 2019 в 13:11

    Если обратиться к книге Роберта Мартина ‘Чистый код’, то он пишет про вариант с отдельным методом i.stack.imgur.com/UwZiI.png

    20 июн 2019 в 13:33

    3 ответа 3

    Сортировка: Сброс на вариант по умолчанию

    Клюнула идейка, которая позволяет уместиться в один блок.

    Использовать можно так:

     Try.AutoRunAction = () => < //code block >; 

    Вот сырая реализация:

     public class Try < // runs on set public static Action AutoRunAction < set < try < value?.Invoke(); >catch < >> > > 
    • то же самое, что из метода, но меньше скобок
    • раньше был геттер, который посоветовали убрать
    • можно еще назвать AutoTryAction
    • принимаю критику
     private static void SetAttributesNormal(DirectoryInfo dir) < AutoTryAction = () => < foreach (var subDir in dir.GetDirectories()) < SetAttributesNormal(subDir); AutoTryAction = () =>subDir.Attributes = FileAttributes.Normal; > >; AutoTryAction = () => < foreach (var file in dir.GetFiles()) < AutoTryAction = () =>file.Attributes = FileAttributes.Normal; > >; > private static Action AutoTryAction < set < try < value?.Invoke(); >catch < >> > 

    Отслеживать
    ответ дан 20 июн 2019 в 16:46
    1,254 7 7 серебряных знаков 26 26 бронзовых знаков
    Своеобразное решение, конечно) И да, зачем Вам геттер?
    20 июн 2019 в 17:29

    Я предлагаю наоборот обьеденить try-catch вместе, т.к. построение фрейма для ловли ошибок считаю затратной операцией. Сделать это можно через цикл. Пусть у вас 10 случаев. Вместо try<>catch<> прийдется писать case x:; break; боюсь сомнительный выигрыш. Разве что. авто-редактор кода не будет превращать это в 5 строк.

    int nmax = 10; int step = 0; while (step < nmax) try < // общий try for (int istep = step; istep < nmax; istep++) switch (istep) < case 0:; break; case 1:; break; // . >> catch

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

     for (int step=0;step <10;step++) try < switch (step) < case 0:; break; //. >> catch <>; 

    Уже как я понял смысла практически не имеет.

    • Вариант с Try(MethodCall) — чуть более затратный по времени.
    • Вариант с using — не получится реализовать. явно, ну развечто если реализовать его так-само как и предыдущий вариант using (var x=new Try(MethodCall)) — что будет изврат. Что бы не было изврата. теоретически можно раскопать il-позицию. но на практике сделать проброс врядли выйдет.

    Вариант 2. Базируясь на варианте 1, и зная номер линии кода, можно шаманить. Но опять же, «условно». Если считать, что каждая строка выполняется один раз, то можно сделать так:

    bool ready = false; int step= 0; while (!ready) try < if (trysafe(ref step)) < method1; /*шаг 1*/ >; if (trysafe(ref step)) < method2; /*шаг 2*/>; ready = true; > catch < >; > // отсекатель bool trysafe(int ref kkey, [CallerLineNumber] int line = -1)

    При исключении, произойдет цикл, и методы которые прошли в if будут пропущены независимо от того было исключение или нет. Отсекатель можно сделать через Dictionary (будет более «умный»). Но код должен предполагать разбивку на шаги как и в предыдущем случае, но шаги можно более «вольно» располагать. Промежутков между шагами не должно быть. Вызов trysafe — должен всегда происходить в разных строках программы. Аргумент kkey можно тоже сократить, и вынести в глобальную область, в зависимости от ситуации.

    P.S. Тихие исключения опасно использовать, потому что в итоге очень сложно отыскать ошибку.

    Отслеживать
    ответ дан 20 июн 2019 в 13:07
    8,012 1 1 золотой знак 21 21 серебряный знак 67 67 бронзовых знаков

    Спасибо, интересная идея, но тут актуально для последовательного вызова методов, а может быть такое, что вложенность. Ну и под «красотой» может быть имел ввиду другое: не то, чтобы по времени было быстро, а чтобы выглядело в тексте кода, как будто без наворотов. Но спасибо, идея интересная!

    20 июн 2019 в 13:29

    Второй вариант — это супер! Но правда не совсем то, потому что код становится более сложным для понимания. Супер — потому, что используются интересные приемы. Может быть, за счет каких — то нетривиальных приемов можно придумать что-то интересное.

    20 июн 2019 в 15:57

    Можно попробовать функционального подход:

    public readonly struct Try  < private readonly Lazy<(T, Exception)>factory; public Try(Func <(T, Exception)>factory) => this.factory = new Lazy<(T, Exception)>(() => < try < return factory(); >catch (Exception exception) < return (default, exception); >>); > public static class TryExtensions < public static TrySelectMany( this Try source, Func> selector, Func resultSelector) => new Try(() => < if (source.HasException) < return (default, source.Exception); >Try result = selector(source.Value); if (result.HasException) < return (default, result.Exception); >return (resultSelector(source.Value, result.Value), (Exception)null); >); public static Try Try(this TSource value) => value; public static Try Select( this Try source, Func selector) => source.SelectMany(value => selector(value).Try(), (value, result) => result); public static Try Throw( this Exception exception) => new Try(() => (default, exception)); public static Try Try(Func function) => new Try(() => (function(), (Exception)null)); public static Try Catch( this Try source, Func handler, Func when = null) where TException : Exception => new Try(() => < if (source.HasException && source.Exception is TException exception && exception != null && ( when == null || when(exception))) < source = handler(exception); >return source.HasException ? (default, source.Exception) : (source.Value, (Exception)null); >); public static Try Catch( this Try source, Func handler, Func when = null) => Catch(source, handler, when); public static TResult Finally( this Try source, Func action) => action(source); public static void Finally( this Try source, Action action) => action(source); > 
    internal static Try Example(int? value) < if (value == null) < return Throw(new ArgumentNullException(nameof(value))); > > 

    Сквозной функционал через обертки

    При разработке мы не редко сталкиваемся с ситуацией, когда при выполнении какой-либо бизнес-логики требуется записать логи, аудиты, разослать оповещения. В общем реализовать некоторый сквозной функционал.

    Когда масштабы производства небольшие, можно особо не усердствовать и все это делать прямо в методах. Постепенно, конструктор сервиса начинает обрастать входящими сервисами для выполнения БЛ и сквозного функционала. А это уже ILogger, IAuditService, INotifiesSerice.
    Не знаю как Вы, а я не люблю много инъекций и большие методы, которые выполняют много действий за раз.

    Можно накрутить на код какую либо реализацию АОП. В стеке .NET такие реализации делают инъекции в ваше приложение в нужные места, внешне похожи на магию 80 уровня и, зачастую, имеют проблемы с типизацией и отладкой.

    Я попытался найти золотую середину. Если данные проблемы не обошли вас стороной, добро пожаловать под кат.

    Спойлер. На самом деле, мне удалось решить чуть больше проблем, чем я описал выше. Например, я могу отдать разработку БЛ одному разработчику, а навешивание сквозного функционала и даже валидации входящих данных — другому одновременно.

    И помогли мне в этом декораторы и надстройка над DI. Кто-то далее скажет, что это прокси, с радостью обсужу это в комментах.

    Итак, что я хочу как разработчик?

    • При реализации БЛ не отвлекаться на левый функционал.
    • Иметь возможность в юнит тестах тестировать только БЛ. Причем я не люблю делать 100500 моков, чтобы отключить весь вспомогательный функционал. 2-3 — еще ладно, но больше не хочу.
    • Понимать, что происходит, не имея 7 пядей во лбу. 🙂
    • Иметь возможность управлять временем жизни сервиса и каждой его обертки ОТДЕЛЬНО!
    • Иметь возможность декомпозировать задачи наиболее оптимально и с наименьшей связностью, чтобы одновременно можно было задействовать как можно больше разработчиков на разные задачи и при этом чтобы они тратили как можно меньше времени на исследование (если разработчику надо разработать БЛ, а параллельно думать, что и как залогировать, он потратит больше времени на исследование. И так с каждым куском БЛ. Куда проще взяться за записи аудитов и распихать их по всему проекту).
    • Оправлять порядком выполнения кода отдельно от его разработки.
     /// /// Обертка для сервиса. /// /// Класс сервиса. public interface IDecorator  < /// /// Делегат для работы декоратора. /// Func NextDelegate < get; set; >>

    Можно использовать как-то так

    interface IService < Response Method(Request request); >class Service : IService < public Response Method(Request request) < // BL >> class Wrapper : IDecorator, IService < public FuncNextDelegate < get; set; >public Response Method(Request request) < // code before var result = NextDelegate().Method(request); // code after return result; >>

    Таким образом, действие у нас будет уходить в глубину.

    wrapper1 wrapper2 service end wrapper2 end wrapper1

    Но, постойте. Это же уже есть в ООП и называется наследование. 😀

    class Service <> class Wrapper1: Service <> class Wrapper2: Wrapper1 <>

    Я как представил, что появится дополнительный сквозной функционал, который придется внедрять по всему приложению в середину или менять местами уже имеющиеся, так у меня на спине волосы дыбом встали.

    Но моя лень — это не уважительная причина. Уважительная причина в том, что будут большие проблемы при модульном тестировании функционала в классах Wrapper1 и Wrapper2, тогда как в моем примере NextDelegate можно просто замокать. Более того, у сервиса и каждой обертки свой собственный набор инструментов, которые инжектятся в конструктор, тогда как при наследовании последняя обертка обязана иметь ненужные инструменты, чтобы передать их родителям.

    Итак, подход принят, осталось придумать, где, как и когда назначать NextDelegate.

    Я решил, что самым логичным решением будет делать это там, где я регистрирую сервисы. (Startup.sc, по умолчанию).

    Вот как это выглядит в базовом варианте

     services.AddScoped(); services.AddTransient(); services.AddSingleton(); services.AddSingleton(sp => < var wrapper2 = sp.GetService(); wrapper2.NextDelegate = () => < var wrapper1 = sp.GetService(); wrapper1.NextDelegate = () => < return sp.GetService(); >; return wrapper1; >; return wrapper2; >);

    В целом, все требования выполнены, но появилась другая проблема — вложенность.

    Эту проблему можно решить перебором или рекурсией. Но под капотом. Внешне все должно выглядеть просто и понятно.

    Вот чего мне удалось добиться

     services.AddDecoratedScoped(builder => < builder.AddSingletonDecorator(); builder.AddTransientDecorator(); builder.AddScopedDecorator(); >);

    А помогли мне в этом вот эти методы расширения

    А помогли мне в этом вот эти методы расширения и построитель декораций

     /// /// Методы расширения для декораторов. /// public static class DecorationExtensions < /// /// Метод регистрации декорируемого сервиса. /// /// Интерфейс сервиса. /// Реализация сервиса. /// /// Коллекция сервисов. /// Построитель декораций. /// Коллекцию сервисов после регистрации декораторов. public static IServiceCollection AddDecorated( this IServiceCollection serviceCollection, ServiceLifetime lifeTime, Action> decorationBuilder) where TImplementation : TDefinition < var builder = new DecorationBuilder(); decorationBuilder(builder); var types = builder.ServiceDescriptors.Select(k => k.ImplementationType).ToArray(); var serviceDescriptor = new ServiceDescriptor(typeof(TImplementation), typeof(TImplementation), lifeTime); serviceCollection.Add(serviceDescriptor); foreach (var descriptor in builder.ServiceDescriptors) < serviceCollection.Add(descriptor); >var resultDescriptor = new ServiceDescriptor(typeof(TDefinition), ConstructServiceFactory(typeof(TImplementation), types), ServiceLifetime.Transient); serviceCollection.Add(resultDescriptor); return serviceCollection; > /// /// Метод регистрации декорируемого сервиса с временем жизни Scoped. /// /// Интерфейс сервиса. /// Реализация сервиса. /// Коллекция сервисов. /// Построитель декораций. /// Коллекцию сервисов после регистрации декораторов. public static IServiceCollection AddDecoratedScoped( this IServiceCollection serviceCollection, Action> decorationBuilder) where TImplementation : TDefinition < return serviceCollection.AddDecorated(ServiceLifetime.Scoped, decorationBuilder); > /// /// Метод регистрации декорируемого сервиса с временем жизни Singleton. /// /// Интерфейс сервиса. /// Реализация сервиса. /// Коллекция сервисов. /// Построитель декораций. /// Коллекцию сервисов после регистрации декораторов. public static IServiceCollection AddDecoratedSingleton( this IServiceCollection serviceCollection, Action> decorationBuilder) where TImplementation : TDefinition < return serviceCollection.AddDecorated(ServiceLifetime.Singleton, decorationBuilder); > /// /// Метод регистрации декорируемого сервиса с временем жизни Transient. /// /// Интерфейс сервиса. /// Реализация сервиса. /// Коллекция сервисов. /// Построитель декораций. /// Коллекцию сервисов после регистрации декораторов. public static IServiceCollection AddDecoratedTransient( this IServiceCollection serviceCollection, Action> decorationBuilder) where TImplementation : TDefinition < return serviceCollection.AddDecorated(ServiceLifetime.Transient, decorationBuilder); > /// /// Метод /// /// /// /// /// private static Func ConstructDecorationActivation(Type implType, Func next) < return x => < var service = (TService) x.GetService(implType); if (service is IDecoratordecorator) decorator.NextDelegate = () => next(x); else throw new InvalidOperationException("Ожидался декоратор"); return service; >; > /// /// Создание фабрики для декорируемого сервиса. /// /// Тип контракта сервиса. /// Тип реализации сервиса. /// Типы делегатов в требуемом порядке. /// Фабрику создания сервиса через DI. private static Func ConstructServiceFactory(Type serviceType, Type[] decoratorTypes) < return sp => < FunccurrentFunc = x => (TDefinition) x.GetService(serviceType); foreach (var decorator in decoratorTypes) < currentFunc = ConstructDecorationActivation(decorator, currentFunc); >return currentFunc(sp); >; > >
     /// /// Построитель настроек декораций. /// /// Интерфейс сервиса. public class DecorationBuilder  < private readonly List_serviceDescriptors = new List(); /// /// Список дескрипторов декораторов. /// public IReadOnlyCollection ServiceDescriptors => _serviceDescriptors; /// /// Добавление декоратора. /// /// Тип декоратора. /// Время жизни декоратора. public void AddDecorator(ServiceLifetime lifeTime) where TDecorator : TService, IDecorator  < var container = new ServiceDescriptor(typeof(TDecorator), typeof(TDecorator), lifeTime); _serviceDescriptors.Add(container); >/// /// Добавление декоратора с временем жизни Scoped. /// /// Тип декоратора. public void AddScopedDecorator() where TDecorator : TService, IDecorator < AddDecorator(ServiceLifetime.Scoped); > /// /// Добавление декоратора с временем жизни Singleton. /// /// Тип декоратора. public void AddSingletonDecorator() where TDecorator : TService, IDecorator < AddDecorator(ServiceLifetime.Singleton); > /// /// Добавление декоратора с временем жизни Transient. /// /// Тип декоратора. public void AddTransientDecorator() where TDecorator : TService, IDecorator < AddDecorator(ServiceLifetime.Transient); > >

    Теперь немного сахара для функциональщиков

    Теперь немного сахара для функциональщиков

     /// /// Базовый класс декоратора. /// /// Тип декорируемого сервиса. public class DecoratorBase : IDecorator  < /// /// Делегат для получения следующего декоратора или сервиса. /// public Func NextDelegate < get; set; >/// /// Выполнить код декоратора с вызовом следующего декоратора. /// /// Тип возвращаемого значения. /// Выполняемый код. /// protected Task ExecuteAsync(Func lambda) < return lambda(NextDelegate()); >/// /// Выполнить код декоратора с вызовом следующего декоратора. /// /// Выполняемый код. /// protected Task ExecuteAsync(Func lambda) < return lambda(NextDelegate()); >>

    Имея такой базовый класс, в декораторе, который его наследует, можно писать как-то так

     public Task MethodAsync(Request request) < return ExecuteAsync(async next =>< // code before var result = await next.MethodAsync(request); // code after return result; >); >

    А если конкретный метод не надо оборачивать текущим декоратором, можно просто написать так:

     public Task MethodAsync(Request request) < return ExecuteAsync(next =>next.MethodAsync(request)); >

    Немного магии все же осталось. А именно — назначение свойства NextDelegate. Сходу не понятно, что это и как использовать, но опытный программист найдет, а неопытному надо 1 раз объяснить. Это как DbSet’ы в DbContext.

    Я не выкладывал это на гит хаб. Кода немного, он уже обобщенный, так что можно дергать прямо отсюда.

    В заключении хочу ничего не говорить.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *