All streams
Search
Write a publication
Pull to refresh
1
0
RouR @RouR

Пользователь

Send message

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

Я так делал когда создавал монолиты. С переходом на небольшие микросервисы это всё кладу в один проект, просто в разных директориях. На хабре была статья про feature-per-folder. Впрочем, есть некоторые исключения для доменых моделей и инфраструктуры, но что касается Requests & Responses - они лежат в том же проекте где и контроллеры и хендлеры.

Что касается контрактов, по swagger спецификации генерируется клиент (C# и/или Typescript) для микросервиса и да, он является отдельным проектом, который импортят все кто хотят работать с этим микросервисом.

//----------------------
// <auto-generated>
//     Generated using the NSwag toolchain v13.13.2.0 (NJsonSchema v10.5.2.0 (Newtonsoft.Json v12.0.0.0)) (http://NSwag.org)
// </auto-generated>
//----------------------

namespace Client.Account.V1_0
{
    using System = global::System;

    [System.CodeDom.Compiler.GeneratedCode("NSwag", "13.13.2.0 (NJsonSchema v10.5.2.0 (Newtonsoft.Json v12.0.0.0))")]
    public partial interface IAccountClient_V1_0
    {
      System.Threading.Tasks.Task<RegisterByEmailResponse> RegisterEmailAsync(string api_version = null, RegisterByEmailRequest body = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken));    
      ...
    }
    
...    

[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.5.2.0 (Newtonsoft.Json v12.0.0.0)")]
    public partial class RegisterByEmailRequest 
    {
        [Newtonsoft.Json.JsonProperty("email", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
        public string Email { get; set; }
    
        [Newtonsoft.Json.JsonProperty("password", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
        public string Password { get; set; }
    
       ...
    
    
    }

Подход не нов, что-то похожее видел в servicestack

Прежде всего, MediatR отделяет обработчики запросов от самих запросов.

Я считаю это неудобным.

Но обработчики запросов - отдельные классы. Конечно, мы можем использовать наследование и вынести всё, что нужно, в базовый класс.

Не наследование, надо использовать DI.

В одном из проектов, вместо использования самого MediatR, я использовал его идею, с немного допиленной реализацией. Примерный код под спойлером. И скажу что это оказалось очень удобно, в одном файле видеть, что прилетает на вход, что должно быть на выходе, какая валидация и что в самом хендлере. Сложная и повторяющаяся логика естественно вынесена в отдельные сервисы, сам хендлер небольшой и довольно понятный. И юнит-тесты тоже хорошо заходят под такую организацию кода.

    [Route("register")]
    [ApiController]
    public class RegisterController
    {        
        [ApiVersion("1.0")]
        [HttpPost("email")]
        public async Task<RegisterByEmail.RegisterByEmailResponse> RegisterByEmail([FromBody] RegisterByEmail.RegisterByEmailRequest request, [FromServices] RegisterByEmail.Handler handler)
        {
            var result = await handler.Handle(request); // это можно улучшить и писать этот бойлерплейт, но считайте что это просто пример
            return result;
        }
		...
        
    }

    public class RegisterByEmail
    {
        public class RegisterByEmailRequest : IRequest<RegisterByEmailResponse>, IValidateable, IHaveUserId, IRequestData
        {
            public string Email { get; set; }
            public string Password { get; set; }
            ...
        }

        public class RegisterByEmailResponse : IErrorable<bool>
        {
            public bool HasError { get; set; }
            public string Message { get; set; }
            public ErrorCode ErrorCode { get; set; }
            public string[] Errors { get; set; }
            public bool Data { get; set; }
        }

        private class Validator : AbstractValidator<RegisterByEmailRequest>
        {
            public Validator()
            {
                RuleFor(field => field.UserId).NotNull().NotEmpty().NotEqual(UserId.Default());
                RuleFor(field => field.Email).NotEmpty().EmailAddress().MaximumLength(Settings.StringMaxLength);
                RuleFor(field => field.Password).NotEmpty().MinimumLength(Settings.PasswordMinLength).MaximumLength(Settings.StringMaxLength);
                ...
            }
        }

        public class Handler : IRequestHandler<RegisterByEmailRequest, RegisterByEmailResponse>
        {
            private readonly IAccountManager _accountManager;
            private readonly ApplicationDbContext _dbContext;
            private readonly ILogger _logger;
            ...

            public Handler(ITracer tracer, ApplicationDbContext dbContext, ...)
            {
                _tracer = tracer;
                _dbContext = dbContext;
                ...
            }

            public async Task<RegisterByEmailResponse> Handle(RegisterByEmailRequest request)
            {
                ...
                return result;
            }
        }
    }
А есть пример, кто попадает под такую формулировку?
Yield хорош для организации конвеера данных. Загрузить с сайта небольшой батч данных в память, отдать через yield, обработать, сохранить, moveNext().
Да, на этом видео они сыграли немного иначе (ну или качество записи повлияло).
Я насчитал 54bpm.
Хочу обратить внимание на очень выраженный шафл-ритм, который основывается на изменении равномерных триолей на две части 1/3 и 2/3. Но в сумме это один такт.
54 *3 = 162 BPM — это если каждую триоль считать одним хитом, что на мой любительский взгляд, неверно.
Дайте послушать блюз в 160 bpm… Texas Flood — Stevie Ray Vaughan

Я насчитал вручную 60bpm.
С учетом комментария выше про 120 bpm, и того что разные люди могут слышать по разному, но как правило быстрее/медленнее строго в 2 раза — в этой композиции точно никак не 160 bpm.

Я пару лет назад пытался для небольшой своей коллекции музыки, автоматом прописать в тэги скорость в bpm. Не работает автоматика. Почти всегда не работает. В итоге определял вручную.
Вы некорректно используете термин обратной связи. Обратная связь, грубо, это когда ученики могут влиять на учителя. Необязательно напрямую, возможно через цепочку родители-администрация. Я понимаю что вы имели ввиду, но термин выбран некорректный.

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

Сама статья началась с примера где инициализация отсутствовала. Так что нет, не должны.
Цитируя документацию, вы выделили жирным немного не тот кусок. Обратите внимание на
do not have to be initialized before being passed in a method call

Естественно что буден некорректным ваш вывод про
out-параметры должны быть проинициализированы
Поэтому их надо строить по модели парковок, а не заправок.
У сертификата есть дата окончания валидности. Раскройте эту тему подробнее:
— обновление сертификата у клиента
— обновление сертификата внутри самого куба.

Я не админ, мне непонятно какой ключ используется самим сервером для подписания CSR во время команды «kubectl certificate approve mycsr».

В вашем примере сертификат валиден 1 год.
А если в кубере 3х месячный Let`encrypt?
public function __construct(ILocator $locator)

Погодите, почему вы это считаете что тут сервис локатор?

Сервис локатор — это некий статический класс, который не передаётся как параметр в конструктор, и именно поэтому получается сильная связанность, что и является проблемой.
Как пример — https://blog.ploeh.dk/2010/02/03/ServiceLocatorisanAnti-Pattern/
15. Был добавлен Swagger c помощью библиотеки Swashbuckle.AspNetCore.Swagger.

16. Нестандартный механизм Authentication потребовал рефакторинга для приведения его к стандартному виду.

Как это связано с миграцией?
Пожалуйста не используйте трюк с mousedown.
Если пользователь промахнулся по кнопке, нажал и не отпустил, то ещё есть шанс всё исправить — увести клик за пределы кнопки, события onclick не будет. Трюк с mousedown ломает этот UX.
И, знаете ли, это очень неприятное, холодное, отупляющее ощущение. Так что пришлось разрешить себе развлекательное чтение. Но, поскольку его сложно назвать полезным, оно остается в категории «Безделье», что объясняет рост этой категории осенью и, одновременно, не выглядит как абсолютно точное решение.

Методы повышения и сохранения работоспособности не стоит воспринимать негативно и называть бездельем. Мы не роботы.
Есть аналогичный тул nuke.build. Его автор, на конференции DotNext, сравнивал с Cake https://youtu.be/7gEqxzD6hbs?t=578

Анемичная модель Это первый антипаттерн

Не всё так однозначно
сельским пейзажем за окном,… оптический интернет от местного провайдера
Это где такое счастье и по каким ценам? Я сталкивался с тем что загородный интернет или 4G или очень дорого.

но вот как ребёнок введёт с клавиатуры, например, математическую или химическую формулу? Никак.
Когда я делал курсовые, то формулы спокойно вводились в том же MS Word. Там всего то надо было настроить панель с формулами.

Выбирая дистанционную или семейную форму обучения, нужно быть честным с собой: переложить ответственность за образование ребёнка на школу не получится. Вся работа по проведению уроков (в случае семейного образования), поддержанию дисциплины и самоорганизованности (в любом случае) полностью ложится на родителей.

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

Information

Rating
Does not participate
Location
Россия
Registered
Activity