Pull to refresh
33
0
Dmitry Tikhonov @0x1000000

Software Developer

Send message

Фильтрация по динамическим атрибутам

Reading time7 min
Views8.3K


В разработке часто возникает необходимость работы с динамическими атрибутами для тех или иных сущностей, более того — сами сущности могут быть полностью динамическими. Думаю, что самым известным таким примером является JIRA, где администраторы могут добавлять или удалять атрибуты тикетов, после чего каждый пользователь потенциально сможет с ними работать (просматривать или изменять их значения). В то же самое время JIRA предоставляет широкие возможности для фильтрации и сортировки тикетов по динамическим атрибутам, что говорит о том, что работа с динамическими атрибутами глубоко интегрирована в хранилище данных JIRA, иначе добиться хорошей производительности при работе с большим количеством данных вряд ли бы получилось. Так, например, если есть тысячи или даже миллионы хранимых объектов (тех же тикетов в JIRA) и если бы фильтрация не была реализована в самом хранилище данных, то необходимо было бы прочитать каждый объект в память приложения, чтобы проверить, не соответствует ли он заданным условиям фильтрации. Очевидно, что такой подход не выглядит особо эффективным.


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

Читать дальше →
Total votes 4: ↑3 and ↓1+2
Comments21

Отслеживание состояния компонентов в Angular c помощью ng-set-state

Reading time12 min
Views5.6K

В предыдущей статье («Angular Components with Extracted Immutable State») я показал, почему изменение полей компонентов без каких-либо ограничений - это не всегда хорошо, а также представил библиотеку, которая позволяет упорядочить изменения состояния компонентов.

С тех пор я немного изменил её концепцию и упростил использование. На этот раз я сосредоточусь на простом (на первый взгляд) примере того, как eё можно использовать в сценариях, где обычно потребовался бы rxJS.

Читать далее
Total votes 3: ↑3 and ↓0+3
Comments2

Реализуем кооперативную многозадачность на C#

Reading time6 min
Views8.9K


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

Читать дальше →
Total votes 11: ↑9 and ↓2+13
Comments38

Кодогенерацию с использованием Roslyn можно использовать и без перехода на .Net 5

Reading time6 min
Views4.2K


Недавно, когда я просматривал новые возможности, которые будут включены в .Net 5, я натолкнулся на одну весьма интересную — генераторы исходного кода. Этот функционал меня особенно заинтересовал, так как я использую аналогичный подход в течение последних… 5 лет, и то, что предлагает Microsoft — это просто более глубокая интеграция этого подхода в процесс сборки проектов.


Примечание: Оригинал был написан в момент, когда релиз .Net 5 только-только собирался выйти, но актуальности этот текст, на мой взгляд, не потерял, поскольку переход на новую версию платформы занимает какое-то время, да и принципы работы с Roslyn никак не поменялись.


Далее я поделюсь своим опытом использования Roslyn при генерации кода, и надеюсь, что это поможет вам лучше понять, что именно предлагает Microsoft в .Net 5 и в каких случаях это можно использовать.

Читать дальше →
Total votes 12: ↑12 and ↓0+12
Comments4

Дерево синтаксиса и альтернатива LINQ при взаимодействии с базами данных SQL

Reading time9 min
Views10K


В этой статье, на примере простых логических выражений, будет показано, что такое абстрактное синтаксическое дерево и что с ним можно делать. Так же будет рассмотрена альтернатива выражениям LINQ для выполнения запросов к SQL базам данных.

Читать дальше →
Total votes 16: ↑15 and ↓1+18
Comments35

Монада «Reader» через async/await в C#

Reading time9 min
Views7K


В моей предыдущей статье я описал, как реализовать паттерн "Монада Maybe" с помощью операторов async / await. В этот раз я расскажу, как реализовать другой популярный шаблон проектирования "Монада Reader", используя те же приемы.


Этот шаблон позволяет неявно передать некий контекст в иерархию вызовов функции без использования параметров или полей классов, и его можно рассматривать как еще один способ реализации внедрения зависимости (Dependency Injection). Например:

Читать дальше →
Total votes 9: ↑9 and ↓0+9
Comments9

Монада «Maybe» через async/await в C# (без Task-oв!)

Reading time14 min
Views15K


Обобщенные асинхронные типы возвращаемых значений — это новая возможность появившаяся в C# 7, которая позволяет использовать не только Task в качестве возвращаемого типа асинхронных (async/await) методов, но также и любые другие типы (классы или структуры), удовлетворяющие определенным требованиям.


В то же время async/await — это способ последовательно вызвать некий набор функций внутри некоторого контекста, что является сущностью шаблона проектирования Монада. Возникает вопрос, можем ли мы использовать async/await для написания кода, который будет вести себя так же, как если бы мы использовали монады? Оказывается, что да (с некоторыми оговорками). Например, приведенный ниже код компилируется и работает:


async Task Main()
{
  foreach (var s in new[] { "1,2", "3,7,1", null, "1" })
  {
      var res = await Sum(s).GetMaybeResult();
      Console.WriteLine(res.IsNothing ? "Nothing" : res.GetValue().ToString());
  }
  // 3, 11, Nothing, Nothing
}

async Maybe<int> Sum(string input)
{
    var args = await Split(input);//Нет проверки результата
    var result = 0;
    foreach (var arg in args)
        result += await Parse(arg);//Нет проверки результата
    return result;
}

Maybe<string[]> Split(string str)
{
  var parts = str?.Split(',').Where(s=>!string.IsNullOrWhiteSpace(s)).ToArray();
  return parts == null || parts.Length < 2 ? Maybe<string[]>.Nothing() : parts;
}

Maybe<int> Parse(string str)
    => int.TryParse(str, out var result) ? result : Maybe<int>.Nothing();

Далее я объясняю, как работает этот код ...

Читать дальше →
Total votes 21: ↑20 and ↓1+19
Comments31

«Reader» monad through async/await in C#

Reading time8 min
Views6.7K

In my previous article I described how to achieve the "Maybe" monad behavior using async/await operators. This time I am going to show how to implement another popular design pattern "Reader Monad" using the same techniques.


That pattern allows implicit passing some context into some function without using function parameters or shared global objects and it can be considered as yet another way to implement dependency injection. For example:


class Config { public string Template; }

public static async Task Main()
{
    Console.WriteLine(await GreetGuys().Apply(new Config {Template = "Hi, {0}!"}));
    //(Hi, John!, Hi, Jose!)

    Console.WriteLine(await GreetGuys().Apply(new Config {Template = "¡Hola, {0}!" }));
    //(¡Hola, John!, ¡Hola, Jose!)
}

//These functions do not have any link to any instance of the Config class.
public static async Reader<(string gJohn, string gJose)> GreetGuys() 
    => (await Greet("John"), await Greet("Jose"));

static async Reader<string> Greet(string name) 
    => string.Format(await ExtractTemplate(), name);

static async Reader<string> ExtractTemplate() 
    => await Reader<string>.Read<Config>(c => c.Template);
Read more →
Total votes 11: ↑11 and ↓0+11
Comments2

“Maybe” monad through async/await in C# (No Tasks!)

Reading time13 min
Views21K


Generalized async return types — it is a new C#7 feature that allows using not only Task as a return type of async methods but also other types (classes or structures) that satisfy some specific requirements.


At the same time, async/await is a way to call a set of "continuation" functions inside some context which is an essence of another design pattern — Monad. So, can we use async/await to write a code which will behave in the same way like if we used monads? It turns out that — yes (with some reservations). For example, the code below is compilable and working:


async Task Main()
{
  foreach (var s in new[] { "1,2", "3,7,1", null, "1" })
  {
      var res = await Sum(s).GetMaybeResult();
      Console.WriteLine(res.IsNothing ? "Nothing" : res.GetValue().ToString());
  }
  // 3, 11, Nothing, Nothing
}

async Maybe<int> Sum(string input)
{
    var args = await Split(input);//No result checking
    var result = 0;
    foreach (var arg in args)
        result += await Parse(arg);//No result checking
    return result;
}

Maybe<string[]> Split(string str)
{
  var parts = str?.Split(',').Where(s=>!string.IsNullOrWhiteSpace(s)).ToArray();
  return parts == null || parts.Length < 2 ? Maybe<string[]>.Nothing() : parts;
}

Maybe<int> Parse(string str)
    => int.TryParse(str, out var result) ? result : Maybe<int>.Nothing();

Further, I will explain how the code works...

Read more →
Total votes 12: ↑10 and ↓2+8
Comments1

Simplify working with parallel tasks in C# (updated)

Reading time7 min
Views22K

image


No doubts that async/await pattern has significantly simplified working with asynchronous operations in C#. However, this simplification relates only to the situation when asynchronous operations are executed consequently. If we need to execute several asynchronous operations simultaneously (e.g. we need to call several micro-services) then we do not have many built-in capabilities and most probably Task.WhenAll will be used:


Task<SomeType1> someAsyncOp1 = SomeAsyncOperation1();
Task<SomeType2> someAsyncOp2 = SomeAsyncOperation2();
Task<SomeType3> someAsyncOp3 = SomeAsyncOperation3();
Task<SomeType4> someAsyncOp4 = SomeAsyncOperation4();
await Task.WhenAll(someAsyncOp1, someAsyncOp2, someAsyncOp4);
var result = new SomeContainer(
     someAsyncOp1.Result,someAsyncOp2.Result,someAsyncOp3.Result, someAsyncOp4.Result);

This is a working solution, but it is quite verbose and not very reliable (you can forget to add a new task to “WhenAll”). I would prefer something like that instead:


var result =  await 
    from r1 in SomeAsyncOperation1()
    from r2 in SomeAsyncOperation2()
    from r3 in SomeAsyncOperation3()
    from r4 in SomeAsyncOperation4()
    select new SomeContainer(r1, r2, r3, r4);

Further I will tell you what is necessary for this construction to work...

Read more →
Total votes 13: ↑12 and ↓1+11
Comments4

Опять про пустые перечисления в C#

Reading time4 min
Views13K
На этот пост мня вдохновила свежая статья на Хабре отсылающая к уже давней проблеме (и советующей статье) о том, как же проверить, что IEnumerable является пустым. Однако в оригинальных статьях, авторы больше сфокусировались на том как оформить проверку, предположив, что проверки вида:

public static bool IsNullOrEmpty<T>(this IEnumerable<T> items)
{
  return items == null || !items.Any();
}

будет достаточно, но на мой взгляд, подобный подход применим далеко не всегда.
Читать дальше →
Total votes 17: ↑14 and ↓3+11
Comments46

Создаем шаблонизируемые переиспользуемые компоненты в Angular 2

Reading time9 min
Views32K
image Много раз слышал утверждение, что Angular 2 должен быть особенно хорош в корпоративных приложениях, поскольку он, мол, предлагает все нужные (и не очень) прибамбасы сразу из коробки (Dependency Injection, Routing и т. д.). Что ж, возможно это утверждение имеет под собой основу, поскольку вместо десятков разных библиотек разработчикам надо освоить один только Angular 2, но давайте посмотрим, насколько хорошо базовая (основная) функциональность этого фреймворка годится для корпоративных приложений.

По моему опыту, типовое корпоративное приложение — это сотни (иногда тысячи) практически идентичных страниц, которые лишь слегка отличаются друг от друга. Думаю, не мне одному приходила в голову мысль, что неплохо бы выделить повторяющийся функционал в отдельный компонент, а специфичное поведение определять через параметры и внедряемые шаблоны. Давайте посмотрим, что Angular 2 может нам предложить.
Читать дальше →
Total votes 24: ↑20 and ↓4+16
Comments27

Information

Rating
Does not participate
Registered
Activity