а я вполне себе делаю Metadata-Driven Framework-и в DDD/CleanArchitecture
При этом не понимаете, что писать в <TargetFramework>. Поменяв net7.0 на netcoreapp2.0, вы сделали хуже, потому что если у .NET 7 поддержка закончилась в мае 2024, у .NET Core 2.0 - в октябре 2018.
При этом не настроили .gitignore, чтобы не тащить в репозиторий мусор.
Вам бы основам сначала уделить внимание, а потом уже хвастаться Metadata-Driven фреймворками. И нет, у меня нет цели вам нахамить или обидеть.
Мне проще делать 1 nuget проект для 10 популярных контейнеров, чем разбивать все на RegisterByAttributes.Abstractions, RegisterByAttributes.Unity и прочее
Если вы хотите, чтобы ваш пакет был полезен другим людям и им пользовались, то как проще вам - не так важно, как проще вашим потенциальным пользователям. А пользователям проще не нести в проект мусор. Даже если 20 кб.
Да, нужно разбивать на несколько пакетов. Unity отдельно, Microsoft DI отдельно. Нет, разбираться в 3+ пакетах никому не придётся. Кому нужен RegistrationByAttributes для Microsoft DI, те по-прежнему поставят один пакет.
Если же вы сделали пакет для себя, то это уже другой вопрос. Как говорится, хозяин - барин. Но тогда не удивляйтесь фидбеку :)
И еще 150+ человек, у которых ушел BoilerPlate регистраций,
Во-первых, не ушёл. Посмею предположить, что самой частой ситуацией у разработчиков является зарегистрировать некий Service как реализацию некого IInterface. В случае Microsoft DI мне нужно написать одну строку (пусть будет синглтон):
services.AddSingleton<IInterface, Service>();
В случае RegisterByAttributes, как ни крути, вам тоже придётся эту одну строку где-то написать, ну только выглядеть она будет атрибутом. Ну и где выигрыш?
Если у вас вдруг на один интерфейс есть 4 разных сервиса - да, окей, вы выиграли и сэкономили 3 строки. Стоило ли оно того? Моё мнение - нет, потому что есть такой принцип наименьшего удивления, которому почему-то редко учат в умных книжках про принципы программирования. Суть в том, что про Microsoft DI - что это такое, как он выглядит и как им пользоваться - знает любой опытный разработчик на .NET, вы простейший web проект не сможете сделать, не наткнувшись на него. Я могу скинуть свой проект коллеге, а он уже заранее будет знать, как в него добавлять новые сервисы. А что такое RegistrationByAttributes? Какая существует веская причина, чтобы заставлять вашего пользователя разбираться в новом пакете, реализующим такую фундаментальную вещь как регистрация сервисов?
Во-вторых, лично я с возрастом начал ценить простоту. Я выберу 200 строк скучного, повторяющегося, но понятного как пять копеек кода, нежели магический чёрный ящик на 20 строк.
Все популярные либы уже поддерживают добавление конфигураций\реализаций и контроллеров БЕЗ ЛИШНИХ ДЕЙСТВИЙ. (AutoMapper, MVC, etc.)
Ну есть Scrutor на худой конец, если очень хочется автомагических регистраций.
Ну и к коду есть вопросы.
case LifetimeManagementType.Singletone:
container.AddSingleton(baseType);
Неужели ничего не щёлкает от Singletone, когда буквально на соседней строчке находится корректный вариант?
case LifetimeManagementType.PerThread:
container.AddScoped(baseType);
PerThread != Scoped, это разные вещи. К слову, это дополнительный довод почему пытаться натянуть один пакет на разные библиотеки DI, - не очень хорошо.
Про написание (в C# все методы пишутся в PascalCase, даже приватные) и в целом неопрятность кода уже упоминали.
в java в finaly можно получить исходное искоючение и что-то сделать (не перехватить но обработать).
А можно пример этого чуда?
В C# не так. Чтобы получить исключение, нужно его перехватить. Перехватывать исключения, не перехватывая их (без catch), нельзя.
я не понимаю как try finaly решает проблему "нужно вывести ошибку в том ui компоненте, откуда пользователь кнопку нажал, а catch у нас где угодно но не там"
Это try-catch:
private void button1_Click(object sender, EventArgs e)
{
try {
throw new InvalidOperationException("The answer to the ultimate question was not 42");
}
catch (Exception ex) {
// Вывести ошибку в том ui компоненте, откуда пользователь кнопку нажал
button1.Text = $"The exception was: {ex.Message}";
// Пробрасываем выше по стеку в "где угодно"
throw;
}
}
У таких конструкций и паттернов есть фатальный недостаток,
Сильно зависит от языка. Например, в Rust есть discriminated unions, #[must_use] и try operator. Вместе они делают работу с results удобной и одновременно убирают заботливо разложенные грабли (например, случайно проигнорировать ошибку нельзя). Win-win.
В C# ничего этого нет, вот и выходит, что работать с исключениями гораздо проще. Но в целом, это не вина паттерна.
а теперь представьте, что нужно генерировать OpenAPI, чтобы клиент понимал, какие коды возможны, а у вас все NotFound и пр. в едином обработчике.
А в чём сложность? Если у вас minimal api, возвращайте из функции Results<>[1], например Results<Ok<Foo>, NotFound, Conflict>. Если MVC, навесьте ProducesResponseType[2].
В .NET вопрос часовых поясов, дат и времён, в общем-то, решён: NodaTime. От вас нужно правильно подобрать входные типы данных (в библиотеке 7 видов дат и времён), остальное вам подскажут типы.
// Find the row containing the target cell.
let row_marker = format!("<row r=\"{}\"", row_num);
if let Some(row_start) = self
.sheet_xml
.windows(row_marker.len())
.position(|w| w == row_marker.as_bytes())
Ладно, я искренне попытаюсь.
При этом не понимаете, что писать в
<TargetFramework>. Поменяв net7.0 на netcoreapp2.0, вы сделали хуже, потому что если у .NET 7 поддержка закончилась в мае 2024, у .NET Core 2.0 - в октябре 2018.При этом не настроили
.gitignore, чтобы не тащить в репозиторий мусор.Вам бы основам сначала уделить внимание, а потом уже хвастаться Metadata-Driven фреймворками. И нет, у меня нет цели вам нахамить или обидеть.
Если вы хотите, чтобы ваш пакет был полезен другим людям и им пользовались, то как проще вам - не так важно, как проще вашим потенциальным пользователям. А пользователям проще не нести в проект мусор. Даже если 20 кб.
Да, нужно разбивать на несколько пакетов. Unity отдельно, Microsoft DI отдельно. Нет, разбираться в 3+ пакетах никому не придётся. Кому нужен RegistrationByAttributes для Microsoft DI, те по-прежнему поставят один пакет.
Если же вы сделали пакет для себя, то это уже другой вопрос. Как говорится, хозяин - барин. Но тогда не удивляйтесь фидбеку :)
Во-первых, не ушёл. Посмею предположить, что самой частой ситуацией у разработчиков является зарегистрировать некий
Serviceкак реализацию некогоIInterface. В случае Microsoft DI мне нужно написать одну строку (пусть будет синглтон):В случае RegisterByAttributes, как ни крути, вам тоже придётся эту одну строку где-то написать, ну только выглядеть она будет атрибутом. Ну и где выигрыш?
Если у вас вдруг на один интерфейс есть 4 разных сервиса - да, окей, вы выиграли и сэкономили 3 строки. Стоило ли оно того? Моё мнение - нет, потому что есть такой принцип наименьшего удивления, которому почему-то редко учат в умных книжках про принципы программирования. Суть в том, что про Microsoft DI - что это такое, как он выглядит и как им пользоваться - знает любой опытный разработчик на .NET, вы простейший web проект не сможете сделать, не наткнувшись на него. Я могу скинуть свой проект коллеге, а он уже заранее будет знать, как в него добавлять новые сервисы. А что такое RegistrationByAttributes? Какая существует веская причина, чтобы заставлять вашего пользователя разбираться в новом пакете, реализующим такую фундаментальную вещь как регистрация сервисов?
Во-вторых, лично я с возрастом начал ценить простоту. Я выберу 200 строк скучного, повторяющегося, но понятного как пять копеек кода, нежели магический чёрный ящик на 20 строк.
Ну есть Scrutor на худой конец, если очень хочется автомагических регистраций.
Ну и к коду есть вопросы.
Неужели ничего не щёлкает от
Singletone, когда буквально на соседней строчке находится корректный вариант?PerThread != Scoped, это разные вещи. К слову, это дополнительный довод почему пытаться натянуть один пакет на разные библиотеки DI, - не очень хорошо.
Про написание (в C# все методы пишутся в PascalCase, даже приватные) и в целом неопрятность кода уже упоминали.
А если все полки уже заняты другими крупногабаритными украшениями для фанатов?
И тумбочки тоже.
А ещё в роутере за 1000 руб. не будет блока Security.
Многие современные ядра Intel идут без SMT.
Если эти ваши соседские мальчишки способны получить доступ к сети zigbee, я бы дал им помигать лампочками уже просто из чувства восхищения.
"У вас нет ни малейшего ё%^5го понятия" это переводится :)
Так они у вас никуда не делись, только теперь размазаны по всему солюшену.
А можно пример этого чуда?
В C# не так. Чтобы получить исключение, нужно его перехватить. Перехватывать исключения, не перехватывая их (без
catch), нельзя.Это try-catch:
К сожалению, это не так. NRT - это рекомендация, компилятор помогает как может, но гарантировать не null не может.
Делать так конечно не надо. Но технически возможность есть.
Сильно зависит от языка. Например, в Rust есть discriminated unions, #[must_use] и try operator. Вместе они делают работу с results удобной и одновременно убирают заботливо разложенные грабли (например, случайно проигнорировать ошибку нельзя). Win-win.
В C# ничего этого нет, вот и выходит, что работать с исключениями гораздо проще. Но в целом, это не вина паттерна.
Ну вот потребность выхода из вложенных циклов - повседневная жизнь.
try-finally не ловит и не обрабатывает исключения (в нём нет блока catch).
А в чём принципиальная разница?
Имхо, это сносно работает только для несложных игрушечных примеров. При первых же сложностях вроде
async/awaitчитаемость сильно падает.Разумеется. В рантайме того же нашего дотнета уйма goto.
А в чём сложность? Если у вас minimal api, возвращайте из функции
Results<>[1], напримерResults<Ok<Foo>, NotFound, Conflict>. Если MVC, навесьтеProducesResponseType[2].В .NET вопрос часовых поясов, дат и времён, в общем-то, решён: NodaTime. От вас нужно правильно подобрать входные типы данных (в библиотеке 7 видов дат и времён), остальное вам подскажут типы.
Linux - достаточно современная операционка?
Это ваша библиотека так с XML работает?
Скажите, а где здесь .NET или C#? Если статья не имеет отношения к указанным технологиям, уберите её из этих хабов, пожалуйста.