YAEC (или еще один почтовый клиент), но на этот раз с LINQ для IMAP
Сегодняшний проект «Еще один почтовый клиент (LINQ to IMAP)» взят с сайта Code Project.
Правда ведь, что выражение «LINQ для IMAP» привлекает и ваше внимание тоже? Вам нравится LINQ, его возможности и отличные перспективы кодирования, которые он предоставляет.
«
Введение
Equinox является клиентской почтовой библиотекой, предназначенной для использования с .NET 4.0 and Mono 2.8. До сих пор в планах была поддержка IMAP и SMTP; POP3 пока не планировался. Она написана на C#, целиком состоит из управляемого кода и ее можно найти на сайте CodePlex. Этой статьей я хочу пробудить интерес к ней и предоставить введение в возможности этой библиотеки, дать небольшое пояснение, почему я решил написать еще один почтовый клиент.
...
Чтобы исследовать это, я реализовал провайдера LINQ, позволяющего доставлять сообщения или части сообщений прямо с сервера, что имеет два преимущества. Первое, не важно, насколько сложен запрос, или сколько сообщений мы требуем, всё это можно сделать за раз используя одну команду доставки; хотя это и сохраняет сетевой трафик, это не то «дымящееся ружье», на которое мы надеялись.
Важным моментом является факт, что мы не должны больше анализировать или составлять карту любых ответов вручную, так как об этом позаботится провайдер LINQ.
Рассмотрим пример простого использования. В нем я получу следующие элементы ото всех непрочитанных за последнюю неделю сообщений:
- Информацию о сообщении
- Uid
- Флаги
- Размер
var query = client.Messages.Where(x => x.Date > DateTime.Today.AddDays(-7)
&& !x.Flags.HasFlag(MessageFlags.Read)).Select(x => new MyContainer
{
Envelope = x.Envelope,
Uid = x.Uid,
Flags = x.Flags,
Size = x.Size
});
Если нам потребуется другой сценарий доставки, мы просто меняем запрос. Мы можем доставить лишь информацию о сообщении (конверт – envelope)
var query = client.Messages.Where( ... ).Select(x => x.Envelope);
Или, наоборот, доставить больше информации:
var query = client.Messages.Where( ... ).Select(x => new SomeClass
{
Envelope = x.Envelope,
Uid = x.Uid,
Flags = x.Flags,
Size = x.Size,
Internal = x.InternalDate,
BodyStructure = x.BodyStructure,
SpecificBodyPart = (Entity) x.Parts("1.2.1.TEXT")
});
Затем можно выполнить повторный запрос по результатам.
foreach(var container in query)
{
Debug.WriteLine(container.Envelope.Subject);
}
Существенно то, что единственной вещью, которую надо поменять при изменении сценария доставки является строка запроса. Как и в случае с LINQ для SQL, нам больше не надо беспокоиться о разборе данных, приходящих от SQL Server, мы просто отображаем ответы в наш объект. Без LINQ нам пришлось бы создавать разные анализаторы для каждого сценария, или создавать один анализатор, способный работать с разными, но довольно ограниченными вариантами ответов, и если мы меняем запрос, то также вынуждены изменить и анализатор.
Как и в случае со многими провайдерами LINQ, имеются ограничения, так как мы вынуждены находиться внутри границ протокола IMAP. Множественные или вложенные операторы Where/Select не разрешены; более точно, нужно только одно предложение Where и одно – Select. За несколькими исключениями никакие другие методы, вроде Any(), Single(), или SelectMany()не поддерживаются. Подробный список поддерживаемых и неподдерживаемых методов, а также инструкции для общих сценариев доставки будут выложены вскоре на CodePlex, но освещение обращения с пользовательскими провайдерами находится вне рамок данной статьи.
...
Статья на Code Project появилась в феврале 2011, поэтому вы, вероятно, спросите, жив ли данный проект?
Вот снимок закладки исходников проекта Crystalbyte Equinox (LINQ to IMAP). Как вы видите на ней прекрасный уровень активности (и что идет работа над POP3).
Когда вы зайдете туда, не забудьте проверить документацию. Там намного больше документации, чем обычно можно ожидать от проектов одного автора.
Например;
Давайте взглянем на последнюю версию, а сначала на снимок решения:
Одна вещь всегда ободряет меня, когда разработчик «ест корм собственной собаки», т.е. использует в кодировании собственные программы.
Например, в файле ImapClient.cs точно используется LINQ для IMAP:
Так, я действительно собираюсь сегодня отказаться от моего почтового клиента? Нет. Но я собираюсь регулярно просматривать этот проект и учитывать его в будущем, если(когда) мне понадобится библиотека IMAP/SMTP/POP3? Да, конечно…