morpher.ru 8 (499) 647 86 54
nowhere@morpher.ru
 
 
Скачать Morpher SDK

Morpher .NET SDK

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

Вот аналог программы "Здравствуй, мир!" с использованием библиотеки Morpher.API.dll:

class HelloMorpher
{
    static void Main()
    {
        Morpher.Russian.IDeclension declension = Morpher.Factory.Russian.Declension;

        Console.WriteLine("Привет {0} от {1}!", 
            declension.Parse("все дотнетчики").Dative,
            declension.Parse("МОРФЕР").Genitive);
    }
}
Привет всем дотнетчикам от МОРФЕРА!
Press any key to continue . . .
    

Как видим, программа склоняет не только общеизвестные слова, но и профессиональные жаргонизмы, редкие слова, псевдонимы, слова с опечатками и т.п.

Обзор SDK

В состав SDK входят следующие библиотеки:

Библиотека Назначение  
Morpher.API.dll Содержит определения интерфейсов IDeclension и INumberSpelling.
Morpher.Russian.dll Содержит реализацию интерфейсов для русского языка. Купить
Morpher.Ukrainian.dll Содержит реализацию интерфейсов для украинского языка. Купить
Morpher.WebService.V2.dll Содержит реализацию для обоих языков, использующую веб-сервис. Кстати говоря, V2 — это не версия библиотеки, а версия веб-сервиса, с которой она работает.
Morpher.AppConfigFactory.dll Содержит вспомогательный класс Morpher.Factory для упрощения создания объектов Declension и NumberSpelling. Позволяет легко переключаться между использованием веб-сервиса и библиотек Morpher.Russian.dll / Morpher.Ukrainian.dll простым изменением app.config.
Morpher.Generic.dll Содержит механизмы абстракции, позволяющие работать с русским и украинским языками через один и тот же generic-интерфейс (IDeclension или INumberSpelling).
Morpher.Dynamic.dll Содержит механизмы абстракции, позволяющие работать с различным языками через один и тот же не-generic-интерфейс (IDynamicDeclension или IDynamicSpeller).

Все библиотеки, кроме Morpher.Russian.dll и Morpher.Ukrainian.dll, бесплатны и распространяются с открытым исходным кодом. Бесплатных библиотек достаточно, чтобы реализовать все функции, доступные в платных библиотеках, при помощи веб-сервиса. Замена реализации на локальные библиотеки не требует перекомпиляции вашего приложения — достаточно положить Morpher.Russian.dll в папку вашего приложения и изменить app.config (web.config).

Russian.IDeclensionUkrainian.IDeclensionRussian.INumberSpellingUkrainian.INumberSpellingRussian.DeclensionРеализуетИспользуетВеб-сервисMorpher.API.dllMorpher.Russian.dllMorpher.Ukrainian.dllnamespace Morpher {Russian.NumberSpellingUkrainian.DeclensionUkrainian.NumberSpellingMorpher.WebService.V2.dllWebServiceMorpher.AppConfigFactoryFactory

«Все проблемы в программировании решаются добавлением нового уровня абстракции... кроме проблемы слишком большого количества уровней абстракции.»

Какие проблемы решает Morpher.API.dll? Для чего нужно разделение интерфейсов и реализации по разным сборкам? Почему бы просто не поместить все классы в одну сборку?

Механизмы абстракции, реализованные в библиотеке, дают ряд преимуществ:

  1. Возможность переключения между веб-сервисом и локальной библиотекой простым изменением конфигурации в app.config или web.config. Перекомпиляции кода не требуется, так как оба механизма склонения имеют один и тот же интерфейс.
  2. Возможность написания кода, работающего для двух языков, русского и украинского. Например, одна и та же функция формирования «суммы прописью» будет работать и для русского, и для украинского (и возможно, для других языков, которые будут добавлены в дальнейшем). В силу схожести этих двух языков интерфейсы для работы с ними также очень похожи, хотя и не идентичны, чего достаточно для написания функций, принимающих язык как параметр. См. пример «Сумма прописью».
  3. Возможность написания кода, где параметры склонения заранее неизвестны (вводятся пользователем, читаются из файла шаблона и т.п.) См. пример FacebookStory.
  4. Использование интерфейсов упрощает тестирование и локализацию проблем. Что делать, если ваша программа зависает, неожиданно завершается или обнаруживает утечки памяти? Один из древнейших способов борьбы с этими проблемами – это отсекание различных частей программы, пока не будет найден «виновный» модуль. Использование интерфейсов упрощает эту процедуру, давая вам возможность подставить вместо веб-сервиса или Morpher.dll тривиальную реализацию-заглушку, возвращающую известные значения для всех входных данных. Тот же подход – использование объектов-имитаторов и заглушек – позволяет изолировать модульные тесты (unit tests) от веб-сервиса и других ненужных зависимостей.

Morpher.AppConfigFactory.dll

Пример файла app.config:

<?xml version="1.0"?> <configuration> <configSections> <section name="morpher" type="Morpher.AppConfig.ConfigurationSectionHandler, Morpher.AppConfigFactory"/> </configSections> <morpher> <objects> <add name="WebServiceClient" type="Morpher.WebService.V2.Client, Morpher.WebService.V2"> <!-- Не забудьте сменить логин и пароль на свои: http://morpher.ru/Register.aspx --> <parameters username="vasily" password="secret"/> </add> </objects> <interfaces> <add object="WebServiceClient" interface="Morpher.Russian.IDeclension, Morpher.API"/> <add object="WebServiceClient" interface="Morpher.Ukrainian.IDeclension, Morpher.API"/> <add object="WebServiceClient" interface="Morpher.Russian.INumberSpelling, Morpher.API"/> <add object="WebServiceClient" interface="Morpher.Ukrainian.INumberSpelling, Morpher.API"/> </interfaces> </morpher> </configuration>

Конфигурация помещается в тег <morpher> и состоит из двух секций: <objects> и <interfaces>. Секция <interfaces> перечисляет интерфейсы из Morpher.API.dll, которые будут использоваться в вашей программе. Если вы не используете какие-либо интерфейсы (например, для украинского языка), то их необязательно указывать в конфигурации. Атрибут object секции <interfaces> ссылается на объект с таким же атрибутом name и означает, что данный объект реализует данный интерфейс. Секция <objects> содержит объекты и параметры их создания. Например, для веб-сервиса необходимо указать имя пользователя и пароль. Тип объекта (атрибут type) задается стандартной строкой, пригодной для передачи в метод Type.GetType (имя типа и имя сборки через запятую).

Существует возможность указать URL веб-сервиса, отличный от http://morpher.ru/WebService.asmx. Такая возможность нужна, если вы используете локальную версию веб-сервиса:

<add name="WebService" type="Morpher.WebService.V2.Client, Morpher.API"> <parameters url="http://localhost/Morpher.asmx" username="pupkin_v" password="secret"/> </add>

Если по каким-либо причинам вас не устроит веб-сервис (основное его ограничение – это скорость), то можно приобрести библиотеку Morpher.Russian.dll, положить ее в папку вашей программы, изменить конфигурацию, и склонение будет работать на порядки быстрее. Не требуется даже перекомпиляции. Вот пример конфигурации, использующей Morpher.Russian.dll:

<morpher> <objects> <add name="RussianDeclension" type="Morpher.Russian.Declension, Morpher.Russian" /> <add name="RussianNumberSpelling" type="Morpher.Russian.NumberSpelling, Morpher.Russian" /> </objects> <interfaces> <add object="RussianDeclension" interface="Morpher.Russian.IDeclension, Morpher.API"/> <add object="RussianNumberSpelling" interface="Morpher.Russian.INumberSpelling, Morpher.API"/> </interfaces> </morpher>

Как видим, функция прописи чисел для украинского (Morpher.Ukrainian.INumberSpelling) реализована в Morpher.dll, а не в UkrMorpher.dll. Это не опечатка, просто исторически так сложилось. В будущем эту нелогичность планируется исправить. Опять же, перекомпиляции вашего кода не потребуется.

Реализованные функции и интерфейсы

1. «Родные» интерфейсы

Каждая функция каждого языка представлена своим интерфейсом в пространстве имен Morpher.<язык>:

Интерфейс Реализация Описание
Morpher.Russian.IDeclension Factory.Russian.Declension Склонение по падежам на русском языке.
Morpher.Ukrainian.IDeclension Factory.Ukrainian.Declension Склонение по падежам на украинском языке.
Morpher.Russian.INumberSpelling Factory.Russian.NumberSpelling Пропись чисел на русском языке.
Morpher.Ukrainian.INumberSpelling Factory.Ukrainian.NumberSpelling Пропись чисел на украинском языке.

Чтобы получить реализацию интерфейса, нужно обратиться к соответствующему статическому свойству класса Factory. Класс Factory вернет реализацию, указанную в вашем app.config.

2. Generic интерфейсы

Русский и украинский языки настолько похожи, что многие функции, например, сумма прописью или формирование пункта "стороны договора" могли бы писаться под копирку с заменой русских слов на украинские. Но мы-то знаем, чем чреват подход copy-and-paste, и знаем, что есть лучшее решение — шаблоны (generics).

Интерфейс Описание
Morpher.IDeclension <TParadigm> Склонение по падежам на русском и украинском.
Morpher.INumberSpelling <TParadigm> Пропись чисел на русском и украинском.

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

Русский   Украинский
namespace Morpher.Russian { public interface IParadigm { string Nominative {get;} // именительный string Genitive {get;} // родительный string Dative {get;} // дательный string Accusative {get;} // винительный string Instrumental {get;} // творительный string Prepositional {get;} // предложный string Locative {get;} // местный (где?) } }
 
namespace Morpher.Ukrainian { public interface IParadigm { string Nominative {get;} // називний string Genitive {get;} // родовий string Dative {get;} // давальний string Accusative {get;} // знахідний string Instrumental {get;} // орудний string Prepositional {get;} // місцевий string Vocative {get;} // кличний } }

Как видим, русские и украинские падежи весьма похожи, но есть и различия. В русском имеется местный падеж (Locative, локати́в), для многих слов совпадающий с предложным (в городе – о городе), но для некоторых отличающийся (в лесу – о лесе). В украинском нет предлога «о» и нет разделения окончаний -е и -у после предлога «в»: в городе – в місті, в лесу – в лісі. Такие формы отнесены к украинскому местному падежу (Prepositional, місцевий).

Звательный падеж в современном русском языке сохранился только у слов Бог – Боже и отец – отче. По сказкам нам знакомы обращения княже, старче. У остальных слов он отсутствует и поэтому в русском интерфейсе IParadigm этого падежа нет. А в украинском звательная форма используется в полной мере, например: доню, синку, пане Олеже, шановний пане Володимиру Володимировичу и т.п. В интерфейсе IParadigm этот падеж называется Vocative (вокати́в).

Несмотря на то, что английские названия русских и украинских падежей практически идентичны, употребление этих падежей может различаться. Например: В соответствии с приказом (твор.) – Відповідно до наказу (род.)

Чтобы преобразовать «родной» интерфейс к generic-интерфейсу, предусмотрен вспомогательный метод AsGeneric:

Morpher.Generic.IDeclension <Morpher.Russian.IParadigm> genericRussianDeclension =
    Morpher.Factory.Russian.Declension.AsGeneric();

3. Dynamic интерфейсы

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

Технические характеристики

Библиотека Платформа Версия .NET
Morpher.API.dll AnyCPU .NET 3.5+
Morpher.Russian.dll AnyCPU .NET 2.0+

Все методы всех классов всех библиотек потокобезопасны. При этом не использовано ни одного объекта синхронизации потоков (классы не имеют модифицируемых полей).

Пример формирования строк вида «[Должность] [ФИО], действующ[ий/ая] на основании...»

Практически в любом договоре можно найти формулировки вида «ООО "Ромашка" в лице генерального директора Волкова С.В, действующего на основании Устава, и гражданка Красношапкова И.К, действующая на основании...» То есть мало того, что должности и фамилии фигурируют в разных падежах, так еще и слова «действующий, именуемый» нужно склонять по родам и падежам. Именно для таких задач и предназначен «Морфер». Пример, формирующий подобные строчки, находится в Morpher SDK, файл Morpher.API.Samples\ДолжностьФиоДействующийSample.cs. Файл содержит собственно функцию и набор тестов к ней, показывающих типичные случаи использования. Тесты запускаются нажатием на желто-зеленый кружок слева от теста:

Пример склонения ФИО и должности в договоре

Проблема: Avast блокирует вызовы веб-сервиса

Симптом: при обращении к веб-сервису через Morpher.API.dll выдается сообщение о таймауте операции:

The request channel timed out while waiting for a reply after 00:00:59.6659809. Increase the timeout value passed to the call to Request or increase the SendTimeout value on the Binding. The time allotted to this operation may have been a portion of a longer timeout.

Если вы используете антивирус Avast, возможно, это он блокирует вызовы, и тогда проблема решается отключением веб-экрана Avast:

Отключение веб-экрана Avast

Я также пытался занести URL веб-сервиса и путь к процессу в "исключения" (доступные через кнопку "Расширенные настройки"), но безупешно. Кстати говоря, до 20 октября 2012 мое тестовое приложение, использующее веб-сервис, работало без проблем, а в конце декабря обнаружилась вышеуказанная проблема.

Предыстория проекта

Morpher .NET SDK пришел на смену библиотеке Morpher.dll, ведущей свою биографию с 2003 года. С тех пор алгоритм библиотеки претерпел множество изменений, но ее внешний интерфейс (API) сохранился таким же, как и в далеком 2003 году. И вот пришло время, когда накопилось несколько причин, требующих изменения интерфейса библиотеки. Чтобы сохранить обратную совместимость (ведь библиотека продолжает использоваться на сотнях предприятий России), было решено начать новый проект с новым API. Новая библиотека получила название Morpher.API.dll.

По сравнению со старой библиотекой, в новый API были внесены следующие изменения:

  • Интерфейсы вынесены в отдельную сборку (Morpher.API.dll), что позволило иметь несколько реализаций этих интерфейсов. Так, в дополнение к обычной реализации, существует реализация, работающая через веб-сервис, что дает возможность протестировать функциональность до покупки библиотеки (а иногда и вместо). Кроме того, наличие интерфейсов облегчает юнит-тестирование, открывая возможность создания прокси-объектов (mocks), так необходимых для избавления от ненужных зависимостей.
  • Имена классов и методов переведены на английский. В старой библиотеке предпочтение отдавалось русским названиям: Предложный вместо Prepositional, Где вместо Locative и т.п. Но как выяснилось из обсуждения с пользователями библиотеки, у многих названия свойств и методов на русском вызывают культурный шок. Исходя из принципа «клиент всегда прав», было решено перейти на латиницу. А так как транслитерация не всегда возможна (predlozhnyi? predlozhniy? predlogny? и т.п.), были выбраны названия на английском.

История изменений

Дата Версия API DLL Версия NuGet  
07.10.2012 1.0.0   Первая версия.
20.10.2012 1.0.1  
  1. В запросы, посылаемые библиотекой веб-сервису, добавлен HTTP заголовок User-Agent с версией библиотеки.
  2. Добавлена возможность не указывать параметр url в конфигурации веб-сервиса. По умолчанию используется http://morpher.ru/WebService.asmx.
17.07.2013 1.0.2   Добавлен конструктор класса WebService, принимающий WebServiceParameters:
    class WebServiceParameters
    {
        public string Url;
        public string Username;
        public string Password;
    }
17.07.2013 1.0.3 1.0.5 Класс WebService переименован в WebServiceClient из-за конфликта имен с другим проектом (breaking change).
24.11.2013 1.0.4   Библиотека Morpher.API.dll разбита на пять составляющих:
  • Morpher.API.dll
  • Morpher.Generic.dll
  • Morpher.Dynamic.dll
  • Morpher.WebService.V2.dll
  • Morpher.AppConfigFactory.dll

Обязательным является использование только библиотеки Morpher.API.dll, все остальные библиотеки могут быть задействованы по мере надобности.

Цель данного изменения в том, чтобы изолировать базовые интерфейсы в сборке Morpher.API.dll, защитив ее тем самым от будущих изменений, не касающихся базовых интерфейсов. Это избавит пользователей от необходимости перекомпиляции при получении обновлений. В ближайшие пару версий Morpher.API.dll должна стабилизироваться и прожить в неизменном виде несколько лет.

17.12.2013 1.0.5 1.0.6
  • В метод IDeclension.Analyse добавлен параметр ParseArgs.
  • Сам метод переименован в Parse (ломать так ломать!)
  • К интерфейсу IGenderParadigm добавлен параметр <T>.
  • Добавлено много XML-комментариев, на русском и на английском.
  • Опубликован пакет NuGet версии 1.0.6.
27.08.2014 1.0.7 1.0.7
  • Исправлена опечатка в классе Gender (см. коммит).
  • Добавлена возможность указания одушевленности склоняемого слова или словосочетания: ParseArgs.IsAnimate.
Скачать Morpher SDK

Комментарии

Вадим 14.07.2013 16:27 UTC

Добрый день.
Есть ли возможность сконфигурировать API без использования app.config?
Т.е. динамически в коде.



Сергей Слепов 17.07.2013 12:13 UTC

Вадим, да, можно. Просто создайте объект класса WebService в коде:

static void Main(string [] args)
{
var parameters = new WebServiceParameters {
Username = "vadim",
Password = "morpher"
};

Morpher.Russian.IDeclension morpher = new WebService (parameters);

Console.WriteLine (morpher.Analyse ("гендир").Dative);
}

Конструктор класса WebService, принимающий WebServiceParameters, только что добавлен – скачайте свежую версию 1.0.2.



Сергей Слепов 20.07.2013 08:06 UTC

Исходный код библиотеки с юнит-тестами и примерами использования теперь доступен на GitHub. Это дает возможность любому желающему с легкостью вносить изменения в код библиотеки при помощи «форков».



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


 

Библиотеки

Заметили опечатку? Выделите слово мышкой и нажмите Ctrl-Enter. Система Orphus

© Сергей Слепов, 2003 - 2017. Перепечатка материалов сайта только с разрешения автора.