Тестовое приложение для тестирования сериализаторов было сделано на библиотеке NFX. Это Unistack библиотека. Честно говоря, я затрудняюсь назвать другой пример Unistack библиотеки. Может быть что-то похожее есть в виде ServiceStack. Хотя ServiceStack, в отличии от NFX, размазан по нескольким dll. Но самое главное, ServiceStack не является Uni, так как его части сделаны немножко по-разному, и он не покрывает такого глобального пространства, как NFX. Но целью данной статьи не является обсуждение концепции Unistack, а одна из особенностей использования NFX.

Как использование NFX повлияло на наше тестовое приложение? Давайте посмотрим.

Тестовое приложение — это консольное приложение. Мы запускаем его и в конце получаем результаты тестов. Тестов может быть много и прогонять все тесты во всех комбинациях за один проход будет глупо. Что бы я сделал без NFX? Скорее всего добавил бы несколько параметров в командную строку, чтобы запускать только нужные мне сейчас тесты. Немножко поработав, я бы добавил конфигурационные параметры в Xml config файл и читал бы их оттуда. Я бы, скорее всего использовал простой массив параметров, имя — значение, в appSettings секции конфигурационного файла. Можно построить более сложную структуру конфигурации, но поддержка этого в .NET не так проста, и я бы на время забыл про сами тесты, а разрабатывал бы и отлаживал этот конфигурационный файл. Нет, я бы не стал делать сложную структуру, потому что — это сложно, а полученные с его помощью преимущества не так велики.

В NFX сделать сложную конфигурацию — просто. Это настолько просто, что это кардинально меняет дизайн нашего тестового приложения.

Предположим, я не знаю ничего о NFX и пытаюсь понять, как это работает, на примере нашего приложения.

Открою конфигурационный файл objgraph.laconf. Вот секция, описывающая сами тесты:

 tests
       {
           test
           {
            type="Serbench.Specimens.Tests.ObjectGraph, Serbench.Specimens"
            name="Warmup ObjectGraph"
            order=000
            runs=1
            ser-iterations=1
            deser-iterations=1
           }
           
           test
           {
            type="Serbench.Specimens.Tests.ObjectGraph, Serbench.Specimens"
            name="Conferences: 1; Participants: 250; Events: 10"
            order=000
            runs=1
            ser-iterations=100
            deser-iterations=100
           ...


Очевидно, секция tests содержит внутри коллекцию секций test, каждая из которых определяет параметры одного теста. Первый параметр — type, опять же очевидно, что он указывает на тип (класс) в assembly. В первом тесте — это соответственно, Serbench.Specimens.Tests.ObjectGraph класс в Serbench.Specimens assembly. Все остальные параметры тоже понятны без дополнительных разъяснений.

Вот секция, описывающая сериалайзеры:

serializers
   {
       // Stock serializers: they use only Microsoft .NET libraries          
       serializer
                    	{
                                type="Serbench.StockSerializers.MSBinaryFormatter, Serbench"
                                name="MS.BinaryFormatter"
                                order=10
                    	}        
       
                    	serializer
                    	{
                                type="Serbench.StockSerializers.MSDataContractJsonSerializer, Serbench"
                                name="MS.DataContractJsonSerializer"
                                order=20
                                _include { file="knowntypes.Conference.laconf"} //include file contents
                    	}
...

Ничего нового, все понятно, разве что появилась конструкция _include, указывающая на файл.

Все это сильно похоже на JSON. Пока что самое большое отличие от него в использовании ‘=’ вместо ‘:’. Еще коллекции не выделяются особым образом, в JSON — это ‘[]’, здесь это — те же ‘{}’.

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

Вот Testкласс, который был указан в config файле:

public abstract class Test : TestArtifact
…
   [Config(Default=100)]
   private int m_SerIterations;
 
   [Config(Default=100)]
   private int m_DeserIterations;
 
   [Config(Default=1)]
   private int m_Runs;


В конфигурации мы имеем

		runs=1
		ser-iterations=100
		deser-iterations=100


а в коде — немножко измененные параметры. К примеру, из m_SerIterations получилось ser-iterations. То есть переменные в конфигурации все пишутся маленькими буквами. Если встречается заглавная буква, то она становится маленькой, но перед ней ставится ‘-’. И префикс ‘m_’ просто отбрасывается.

Стоп, а как же мы поймем, что переменная из кода становится конфигурируемой? Очевидно, что с помощью атрибута [Config].

Хорошо, понятно, как задаётся конфигурация. А как она используется? Попробую разобраться с секцией serializers.

Нахожу ее в в классе TestingSystem:

       public const string CONFIG_SERIALIZERS_SECTION = "serializers";
       public const string CONFIG_SERIALIZER_SECTION = "serializer";
 
...
         foreach(var snode in node[CONFIG_SERIALIZERS_SECTION].Children.Where(cn => cn.IsSameName(CONFIG_SERIALIZER_SECTION)))
         {
             var item = FactoryUtils.Make<Serializer>(snode, args: new object[]{this, snode});
             m_Serializers.Register( item  );
             log(MessageType.Info, "conf sers", "Added serializer {0}.'{1}'[{2}]".Args(item.GetType().FullName, item.Name, item.Order));
         }
 
         if (m_Serializers.Count==0)
...


Теперь я вижу работу с контейнером. Регистрируется отдельный Serializer класс для каждого serializer из конфигурации.

А что такое m_Serializers?

       private OrderedRegistry<Serializer> m_Serializers = new OrderedRegistry<Serializer>();


Похожий код — для m_Tests, та же регистрация, но уже Test классов.

doTestRun() метод — для запуска одного тестового прохода (runs=1). Он запускает сначала нужное количество итераций сериализации (ser-iterations=100), потом нужное количество итераций десериализации (deser-iterations=100). Все эти параметры задаются в конфигурации.

Хорошо, с деталями вроде все понятно. Вернусь назад.

Резюме


Если теперь заново взглянуть на приложение, то увидим, что это уже не типичное консольное приложение с парой строчек конфигурации. Теперь конфигурация разрослась и стала по размеру соизмерима непосредственно с кодом на С#. Конфигурация стала похожа на интерфейсы к приложению. У нас нет UI, это по-прежнему консольное приложение, но насколько сильно бизнес логика переместилась из кода в конфигурацию!

Насколько интересной стала конфигурация. Здесь есть и настройки всего приложения, и настройки отдельных классов. Теперь классы больше похожи на бизнес-объекты.

И — да, вы правы. Теперь все приложение можно разрабатывать, начиная с определения конфигурации, которая теперь является нашим бизнес-интерфейсом. Уже после этого можно приступать непосредственно к дизайну классов и кодированию.

Давайте еще раз посмотрим, что мы добавили и что получили взамен.

Мы стали использовать конфигурационную систему из NFX. Мы сначала создали конфигурационный файл с бизнес-интерфейсами:

  • Вот тесты, которые мы хотим выполнять.
  • Вот сериалайзеры, которые мы хотим тестировать.
  • Вот тестовые данные.
  • Вот итоговые данные и их форматы.


Другими словами, мы сначала описали модель нашего тестового приложения в конфигурации.

Следующим шагом мы создали конкретные классы и связали их с конфигурацией.

Вопросы от программиста



Здесь мы связываем конфигурацию с конкретными классами не во время компиляции приложения, а во время его работы. Как сильно это увеличит вероятность run-time ошибок?

Да, теперь если мы ошибемся, к примеру, в имени класса в конфигурации, то эта ошибка будет обнаружена не при компиляции, я только во время работы приложения. NFX загружает конфигурацию при старте приложения. Поэтому большая часть ошибок обнаруживается сразу же при старте, а не во время работы отдельного класса. При этом диагностика однозначно локализует ошибки. В результате вероятность run-time ошибок повышается незначительно.


Весь NFX находится в одном assembly. В нем масса классов, которые я не буду использовать. Мешаются ли они?

Первое, что вы заметите, когда первый раз скомпилируете приложение под NFX, это — как быстро пройдет компиляция. NFX — библиотека, сделанная программистами для программистов. И предназначена она для самых критических случаев: тысячи серверов, миллионы сообщений и т.п. Все, что тормозит, было переработано или полностью заменено. Кроме того, NFX — это библиотека для серверов, размер для нее не так важен. Хотя не думаю, что 1.5 МБ (размер NFX) будет велика и для клиентских приложений.


А можно ли использовать NFX в IoT устройствах? Возможностей у нее много, и все это — в одном файле.

Мы над этим, честно говоря, не думали. Все же NFX, не забывайте, работает на .NET. Если будут устройства с загруженным .NET, то — почему бы и нет.


Как я вижу, конфигурация задается в каком-то новом языке. Честно говоря, не хочу изучать еще один язык. Есть какие-нибудь альтернативы?

Да, есть. В NFX конфигурации можно описывать еще на Laconic или на XML. При этом при переходе между Laconic и XML вам не придется менять абсолютно ничего в коде.

Почему для конфигураций был использован язык Laconic, а не JSON? Он не сложнее JSON и выучить его можно за 5 минут. К сожалению, JSON, по ряду конкретных причин, плохо подходит для конфигурационных файлов.

Комментарии (60)


  1. lair
    29.07.2015 21:36
    +1

    Первое, что вы заметите, когда первый раз скомпилируете приложение под NFX, это — как быстро пройдет компиляция.

    Хм, приложения «под NFX» чем-то отличаются от приложений под «обычный .net» в части компиляции? Это не .net? Используется другой компилятор?

    А можно ли использовать NFX в IoC устройствах?

    Что такое «IoC-устройство»?

    К сожалению, JSON, по ряду конкретных причин, плохо подходит для конфигурационных файлов.

    Каких именно «конкретных причин»?


    1. Leo_Gan Автор
      29.07.2015 22:02

      Сразу оговорюсь, я здесь выступаю в виде пользователя и мало что знаю о потрохах NFX. Насколько понимаю, количество referenced assembly сильно влияет на время компиляции. Здесь у нас 1 шт. Может есть какие-нибудь доп.оптимизации (вопрос к разработчикам. Ау?). Обычно на моем лаптопе приложения, с кот.я работаю, компилируются несколько [ десятков] секунд. А здесь — доли секунд.

      Оопс… IoT (Internet of Things) — спасибо за найденную ошибку!!!

      C JSON: один пример: нет стандартного метода задавать имя объекта. Т.к. к примеру, class Test. В XML будет: <ns:Test>…, а в JSON: { _name: «Test»… что-то типа этого, т.е.выдумывать нестандартные методы, чем, кстати, многие и занимаются.


      1. lair
        29.07.2015 22:17

        Насколько понимаю, количество referenced assembly сильно влияет на время компиляции.

        Есть хотя бы одна статья, подтверждающая это предположение?

        Здесь у нас 1 шт.

        А от System вы не зависите?

        Обычно на моем лаптопе приложения, с кот.я работаю, компилируются несколько [ десятков] секунд. А здесь — доли секунд.

        Solution, который у меня был по руками (13 проектов, реально собиралось 8, 55 nuget-пакетов зависимостей, не считая системных сборок), собрался за несколько (меньше пяти) секунд (не десятков), причем большую часть этого времени система забирала нехватающие пакеты. Окей, clean solution, build solution — на билд 13 проектов уходит три секунды, причем зависимостй там нигде не меньше пяти, а в фронтендовых — больше двух десятков на проект.

        C JSON: один пример: нет стандартного метода задавать имя объекта. Т.к. к примеру, class Test. В XML будет: <ns:Test>…, а в JSON: { _name: «Test»… что-то типа этого, т.е.выдумывать нестандартные методы, чем, кстати, многие и занимаются.

        А нет такой вещи, как «имя объекта», поэтому и задать «стандартными способами» его нельзя. Обычно такие вещи прекрасно решаются через key-value pair.


        1. Leo_Gan Автор
          29.07.2015 23:22

          Подумал-подумал. Вы правы. Какая разница 5 сек или 0.5 сек. Пусть даже 30 сек. на компиляцию — это совершенно неважно. Пойду текст поправлю.

          «имя объекта», тоже лажанулся. должно быть «имя класса».


          1. lair
            29.07.2015 23:27

            Какая разница 5 сек или 0.5 сек. Пусть даже 30 сек. на компиляцию — это совершенно неважно.

            Да разница-то есть, только вопрос, есть ли на самом деле этот разброс времени, или нет.

            «имя объекта», тоже лажанулся. должно быть «имя класса».

            Во-первых, аналогично, и в XML, и в JSON нет такой вещи, как «имя класса», потому что они не предназначены для объектно-ориентированной парадигмы. А во-вторых, и там, и там есть расширение, позволяющее указать тип элемента — в XML это xsi:type, в JSON — $type. Другое дело, что и там, и там без него чаще всего можно обойтись, если продумать семантику документа.


            1. Leo_Gan Автор
              29.07.2015 23:40

              В laconic я могу написать:
              Tests {… }
              Как я это сделаю в JSON?

              По сути я с вами согласен. Давайте будем считать laconic расширением JSON, заточенным под данную задачу.


              1. lair
                29.07.2015 23:42
                +1

                Как я это сделаю в JSON?

                А что вы хотите сделать? Что такое «Tests»? Какое место в модели оно занимает?

                Давайте будем считать laconic расширением JSON, заточенным под данную задачу.

                Нет, laconic — не расширение JSON, потому что laconic не является валидным JSON.

                Собственно, вопрос, по каким же конкретным причинам json не подходит для конфигурационных файлов, остался открытым.


                1. itadapter
                  01.08.2015 23:00

                  Laconic nikakogo otnoheniya K JSON ne imeet voobshe.

                  Eto format imenno dlya configa. on podderjivaet takie udobnie veshi kak:
                  1. bukvalnie stroki a-la C# $" i can span many lines \not escape"
                  2. uproshennuju grammatiku bez operatorov «my+va-+-+lue=1 2 2», imena kluchei moigyt tozhe byt strokami
                  3. commenti: sngle line, multi line
                  4. true hierarchy without root object/array requirements

                  i chto samoe glavnoe, chto LACONIC voobshe ne trebuetsya.
                  Vy mojete napisat tot-zhe file s extension XML i vse budet rabotat na XMLe

                  look, this is NFX config in XML:
                  github.com/aumcode/nfx/blob/master/Source/Testing/Manual/WinFormsTest/WinFormsTest.configuration


                  1. lair
                    01.08.2015 23:06

                    Laconic nikakogo otnoheniya K JSON ne imeet voobshe.

                    Спасибо, я в курсе. Утверждение «давайте будем считать laconic расширением JSON» принадлежит Leo_Gan.

                    Меня существенно больше интересует, почему JSON не подходит для задачи, описанной в посте.


        1. itadapter
          29.07.2015 23:42

          yes, and this is extremely inconvenient.
          try to convert this to JSON:

          node
          {
          // no-log=true
          server=local{ binding=sync{tcp-window=16k} binding=async{ tcp-window=16k}}
          welcome=$«Hello {0},
          — you have connected to {1}»
          }


          1. lair
            29.07.2015 23:48
            +1

            (Хабр — русскоязычный сайт, по-английски я могу и на SO поговорить)

            А что здесь надо сконвертировать в JSON? Какая модель за этим стоит, какая у нее семантика?

            (я, заметим, не считаю, что JSON идеально подходит для конфигов, но есть ведь и YAML)


          1. mayorovp
            31.07.2015 13:03
            -1

            {
              "server": {
                "type": "local",
                "bindings": [
                  { "type": "sync", "tcp-window": "16k" },
                  { "type": "async", "tcp-window": "16k" }
                ],
                "welcome": "«Hello {0}, \n— you have connected to {1}»"
              }
            }
            


            Чего еще не хватает?..


            1. itadapter
              01.08.2015 03:43

              Why «Type»? Why not «name»? or anything else?

              so how will this look in JSON?

              friend=true
              {
                type="Oslik"
                name="Drug Ezhika"
              }
              


              1. mayorovp
                01.08.2015 11:25
                +1

                Мой конфиг — как хочу, так и обзываю параметры.


                1. itadapter
                  01.08.2015 19:35

                  вы даже не прочитали внимательно ответ.
                  в JSON невозможно создать ноуд валуе без имени в принципе.

                    node=45{} 
                  


                  в ХМЛ и прочих иерархических форматах запросто.
                  ЙСОН это object формат, у него нет корня без аттрибутов
                  поэтомы я вас попросил написат на JSON- вы же даже не удосужились вникнуть в проблему —
                  в вашем примере будет введен «type» суррогатныи ноуд. А если ноуд с таким именем уже есть?

                  вообше поражает что здесь никто не пытается даже прочесть ответ, не говоря о вникании в суть


                  1. lair
                    01.08.2015 20:31

                    Вы проблему сначала описали бы, что ли. Я, заметим, вас уже просил об этом.


                  1. mayorovp
                    01.08.2015 21:49

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

                    Но так программы не пишутся! Объектная модель, схема, или что-там-еще файла конфигурации всегда составляется с учетом ограничений парсера и формата.

                    К чему это я? Вернемся к вашему вопросу:

                    А если ноуд с таким именем уже есть?
                    Я просто не будут выбирать это имя для других нодов.


                    1. itadapter
                      01.08.2015 22:46
                      -1

                      mne kajetsya chto sushestvuet model?
                      konechno ona sushestvuet. mnogie veshi configuriruytsya iz XML kotoriy byl napisan esho v 2002 gody.

                      a kto vam skazal chto configurazija voobshe imeet kakoe-libo otnoshenie k JSON?

                      vot primer configurazii v NFX:

                         c:\>dosomething.exe "c:\input.file" "d:\output.file" -compress level=100 method=zip -shadow fast -large
                      
                            [args ?1="c:\input.file" ?2="c:\output.file"]
                              [compress level="100" method="zip"]
                              [shadow ?1="fast"]
                              [large]
                       

                      eto odin prosto primer.
                      potom vy mojete prosto tak «prisobachit eto v klass:

                          [Config]
                          public int CompressionLevel....
                      

                      ..i ne vazhno voobshe dannie prishli iz XML, INI, command args — eto prosto derevo.
                      Eto kak raz u vas pochemy-to kasha i tight-coupling mezhdu FORMATOM i soderjimim

                      configuraizja — eto derevo v pamyati.
                      XML laconic ili yaml — eto voobshe nevazhno.

                      A mojet ya xochu derjat eto v SQL servere? pochemu net.

                      s kakogo boku tyt JSON? on voobshe dlya etoi zadachi nikak ne podxodit


                      1. lair
                        01.08.2015 23:09
                        +1

                        configuraizja — eto derevo v pamyati. [..] s kakogo boku tyt JSON? on voobshe dlya etoi zadachi nikak ne podxodit

                        Ну, это вы зря. Как раз для отображения «дерева в памяти» JSON подходит ничем не хуже предлагаемого вами же SQL.


            1. itadapter
              01.08.2015 19:43

              кстати, а где комментарии в JSON?
              конфиг фаил на 300 строчек, из них болше 25% комменты?

              example:

                  instrumentation 
                  {
                      name="Instruments" 
                      interval-ms="4395"
                      //self-instrumented=true
              		
              	   /*	provider
              		{
              			name="Telemetry Instrumentation Provider"
              			type=$(/gv/types/$instr-nop) 
              		}  */
                         
                      provider 
                      { 
                          name="Telemetry Instrumentation Provider"
                          type=$(/gv/types/$instr-telemetry) 
                          use-log="false"
                          receiver-node="sync://127.0.0.1:$(/gv/services/$sync-telemetry)"
                      }
                  }
              



              1. lair
                01.08.2015 20:34
                +1

                Комментариев в json, действительно нет. Зато они есть в yaml и hocon (а так же в xml).


                1. itadapter
                  01.08.2015 22:56

                  neponyatno pochemy vse zaziklilos na JSON.

                  Skajite, pochemy configurazija ne mojet byt' naprimer v baze ili commandnoi stroke ili v Mongo documentax?

                  Pochemy configurazija ne mojet «sobiratsya» dynamicheski is raznix fomatov (naprimer v baze polya, v file XML)?

                  Vy chto ne ponimaete chto configurazija eto prosto ierarxija imenovanix znacheniy.
                  Da mojno ispolzovat JSON kak ODIN IZ formatov, no on ochen neudoben.

                  Kstati, kogda menya zakalibal XML, ya reshil ispolzovat JSON i napisal JSONCOnfig za gde-to 15 miunut.
                  Potom ya osoznal chto eto ochen neudobno, imenno v svazi s otsutstviem kommentariev
                  da i strukturno v JSONE v prinzipe net noudov chistoi ierarxii kotorie est v XMLe tom je


                  1. lair
                    01.08.2015 23:04

                    neponyatno pochemy vse zaziklilos na JSON.

                    Мне тоже не понятно, зачем вы спрашиваете «а как сделать вот такое в JSON».

                    Skajite, pochemy configurazija ne mojet byt' naprimer v baze ili commandnoi stroke ili v Mongo documentax?
                    Pochemy configurazija ne mojet «sobiratsya» dynamicheski is raznix fomatov (naprimer v baze polya, v file XML)?

                    Может.

                    Da mojno ispolzovat JSON kak ODIN IZ formatov, no on ochen neudoben.

                    Для кого как.

                    da i strukturno v JSONE v prinzipe net noudov chistoi ierarxii kotorie est v XMLe tom je

                    Простите, чего именно нет в JSON? Можно на примерах?


                    1. itadapter
                      01.08.2015 23:06

                      posmotrite vishe comment, tam conkretniy primer


                      1. lair
                        01.08.2015 23:08

                        Я не знаю, что вы в этом примере называете «noudov chistoi ierarxii», так что затрудняюсь как-то аргументированно с вами спорить о том, что есть в JSON, а чего нет.


                        1. itadapter
                          01.08.2015 23:25

                          CTRL+F «Oslik» — tam primer imenno po etomu.

                          Dopustim u vas est attribut «type». Ktoto sverxy predlagal ego ispolzovat. Vopros: kak vyrazit takoe derevo na JSON:

                          friend{name=«Ezhik» age=3 type=«CloseFriendConnection»}

                          ili takoe:
                          connect
                          {
                          site=http://yahoo.com{}
                          site=http://google.com{name=«Google» type=""}
                          }


                          1. lair
                            02.08.2015 01:02

                            Я еще раз спрашиваю: так все-таки, семантика какая? А то если переводить в лоб, что все же тривиально:

                            friend{name=«Ezhik» age=3 type=«CloseFriendConnection»}

                            friend: {name: "Ezhik", age: 3, type: "CloseFriendConnection"}
                            


                            connect
                            {
                            site=http://yahoo.com{}
                            site=http://google.com{name=«Google» type=""}
                            }

                            connect: 
                              [
                              "http://yahoo.com",
                              {"http://google.com": {name: "Google", type: ""}}
                              ]
                            


                            1. itadapter
                              02.08.2015 01:08

                              a esli «friend» vstrechaetsya >1 raza podryad?

                              group
                              {
                                 friend{}
                                 friend{}
                              }
                              


                              i teper nado delat array na JSONe, v etom i neudobstvo.
                              To pole, to array. JSON eto OBJECT NOTATION format. XML i Laconic eto DATA delimitation format

                              v etom vsya razniza


                              1. lair
                                02.08.2015 01:12

                                i teper nado delat array na JSONe, v etom i ne udobstvo.

                                Не вижу никакого неудобства. Полезно заранее представлять себе множественные отношения в своих данных.

                                To pole, to array.

                                Вообще-то, всегда поле.

                                JSON eto OBJECT NOTATION format. XML i Laconix eto DATA delimitation format

                                Ничего не знаю про laconix, а XML — это язык разметки. По большому счету, разметки чего угодно. JSON — действительно, объектная нотация, но если мы и конфиг потребляем как объектную структуру, то ничего плохого в этом нет.

                                Что в очередной раз возвращает нас к вопросу: чем JSON не подходит для решения задачи, описанной в посте?


                            1. itadapter
                              02.08.2015 01:12

                              posmotrite, u vas «yahoo» eto string v arraye, a google eto object s property imenem «google.com»
                              vas ot etogo ne korobit?

                              teper napishite eto na XML (zabudem pro laconic, on yavno mazolit glaza)
                              i srazy vse stanet proshe

                              <connect>
                                <site>http://yahoo.com</site>
                                <site name="Google" type="...">http://google.com</site>
                              </connect>
                              


                              1. lair
                                02.08.2015 01:14

                                posmotrite, u vas «yahoo» eto string v arraye, a google eto object s property imenem «google.com»
                                vas ot etogo ne korobit?

                                Нет. Я специально так написал, чтобы показать, что JSON прекрасно вариативен, если мы хотим получать компактные нотации. Если вы хотите строгую запись, то вот она:

                                connect: 
                                  [
                                  {"http://yahoo.com": null},
                                  {"http://google.com": {name: "Google", type: ""}}
                                  ]
                                


                                1. itadapter
                                  02.08.2015 01:19
                                  -1

                                  ya ne poimu smisla voobshe etogo voprosa. ya otvetil: JSON eto OBJECT notation format.
                                  Dlya postroeniya ABSTRACTNIX ierarxiy pamyati on neudoben xotya by potomu chto
                                  on trebyet «key»/value" mapping. Derevo v NFX etogo ne trebuet voobshe.
                                  Naprimer vy mojete imet xot 100 noudov s odnim i tem je imenem.
                                  Eto delaetsya legko na XMLe, t.k on format razmetki texta prosto i vse.

                                  Laconicn udobnee XMLa v razy. Seichas u menya realno ostalos tolko neskolko starix prilojeniy
                                  gde ispolzyetsa XML — prosto uje davno.

                                  Esli vam lichno nujen JSON eto vashe pravo, no vy ubedites sami chto isplzovat ego vmesto Laconic formata
                                  v razy neudobnee. Ya proverial + moi partner proveryal. My daje vybrosili JSONconfig iz NFX t.k ne bylo ni odnoi zadachi.


                                  1. lair
                                    02.08.2015 01:26
                                    +2

                                    ya ne poimu smisla voobshe etogo voprosa. ya otvetil: JSON eto OBJECT notation format.

                                    Как это мешает его применению для задач в посте?

                                    Dlya postroeniya ABSTRACTNIX ierarxiy pamyati on neudoben

                                    У нас не абстрактная иерархия, у нас вполне конкретная задача…

                                    Naprimer vy mojete imet xot 100 noudov s odnim i tem je imenem.

                                    … в рамках которой это ваше требование избыточно. Откроем и посмотрим:

                                    tests
                                           {
                                               test
                                               {
                                               ...
                                               }
                                               test
                                               {
                                                ...
                                               }
                                           }
                                    
                                    serializers
                                          {
                                               serializer
                                               {
                                               ...
                                               }        
                                               serializer
                                               {
                                               ...
                                               }        
                                          }
                                    


                                    Это же два тривиальных массива: tests и serializers, и их можно так и записать, не потеряв ни грама семантики.

                                    Esli vam lichno nujen JSON eto vashe pravo, no vy ubedites sami chto isplzovat ego vmesto Laconic formata v razy neudobnee.

                                    Где можно взять пакет для чтения laconic, чтобы я мог в этом убедиться?


                                    1. itadapter
                                      02.08.2015 02:34

                                      Vy mne predlagaete pisat' config v kajdom projekte svoi s nylya?
                                      Ya je vam obyasnil chto NFX.Environment.Configuration eto ne parsanie filov a zeliy
                                      framework, kotoriy imeet okolo 10+ features: macros, variables, recursion, injection etc…

                                      Smotrim tyt:
                                      blog.aumcode.com/2013/08/aum-configuration-as-facilitated-by-nfx.html

                                      Где можно взять пакет для чтения laconic, чтобы я мог в этом убедиться?

                                      Laconic mojno chitat xot na urovne Lexera xot parsera no zachem?
                                      vam nujno Configuration a ne Laconic. Laconinc, command args ili XML eto ne vajno — on sam vse poimet.

                                      smotrite v kod na primere:
                                      driver program: github.com/aumcode/nfx/blob/master/Source/Tools/gluec/Program.cs
                                      conf applied to class: github.com/aumcode/nfx/blob/master/Source/NFX/Glue/Tools/GluecCompiler.cs

                                      Naskolko ya ponyal Leo_gan vzyal primer is proekta SERBENCH
                                      kotoriy tyt:
                                      github.com/aumcode/serbench

                                      vse eti configi mojno napisat na XMLe, configurazija vstroena v NFX Application
                                      koei i yavlaetsya SERBENCH.

                                      posmotrite v kod:
                                      github.com/aumcode/serbench/blob/master/Source/sb/sb.laconf
                                      etot je file mojete peredelat v XML i prosto pomenyaite extension. syt taje, koda net


                                      1. lair
                                        02.08.2015 13:17

                                        Vy mne predlagaete pisat' config v kajdom projekte svoi s nylya?

                                        Нет, я предлагаю четко отдавать себе отчет, какую пользу для конкретного решения привносит каждый из его компонентов. Вот Leo_Gan в своем посте явно не может различить, что в архитектуру привносит configuration-driven development, что — laconic, а что — nfx.

                                        zeliy framework, kotoriy imeet okolo 10+ features: macros, variables, recursion, injection etc…

                                        И что из этого понадобилось в решаемой задаче?

                                        Зато этот фреймворк до сих пор не научился — или не научился конкретный программист, им пользующийся — выдавать полностью типизированные аксессоры, чтобы вместо foreach(var tnode in node[CONFIG_TESTS_SECTION].Children.Where(cn => cn.IsSameName(CONFIG_TEST_SECTION))) (серьезно? строковые константы? два уровня вложенности для простого массива?) можно было писать foreach(var tnode in node.Tests).

                                        Laconic mojno chitat xot na urovne Lexera xot parsera no zachem?

                                        Чтобы сравнить, насколько легко работать с ним по сравнению с JSON и YAML.

                                        vam nujno Configuration a ne Laconic. Laconinc, command args ili XML eto ne vajno — on sam vse poimet.

                                        Окей, где можно взять вашу конфигурацию в виде пакета?


                                        1. itadapter
                                          04.08.2015 01:22

                                          ya ponimaju o chem vy govorite. K sojaleniju «zaxvat» features kotoriy obespechivaet NFX
                                          ne ocheviden v scope takix statei kak zdes, poka s etim frameworkom ne porabotaesh na neskolkix raznix zadachax
                                          budet ne vse ponyatno. Vy mojete skazat chto eto ploxo. Pust tak. Real'no mnogie veshi
                                          vyglyadyat ne tak kak dictuet mainstream. Typizazii configa sdelanav NFX no ne tak kak vami ojidaetsya.
                                          Delo v tom chto config eto kak raz prekrasnoe mesto (takje kak DataAccess) dlya dynamic-like languages.
                                          To chto tam napisan kod po injekzii dependencies — eto sdelano spezialno, no sut ne v etom (eto voobshe tema drugogo posta).

                                          tolko-configuraziju otdelno vzyat' nelzya. ya mnogo raz govoril pochemy.

                                          mojno NFX zelikom t.k on UNISTACK.

                                          pm>install-package NFX


                                          1. lair
                                            04.08.2015 11:58

                                            ya ponimaju o chem vy govorite

                                            «вообше поражает что здесь никто не пытается даже прочесть ответ, не говоря о вникании в суть „

                                            K sojaleniju «zaxvat» features kotoriy obespechivaet NFX ne ocheviden v scope takix statei kak zdes

                                            Вот именно поэтому я и говорю, что преимуществ в контексте статьи либо нет, либо они не показаны.

                                            Typizazii configa sdelanav NFX no ne tak kak vami ojidaetsya. Delo v tom chto config eto kak raz prekrasnoe mesto (takje kak DataAccess) dlya dynamic-like languages.

                                            Не, не убедили. Как раз динамические (и псевдодинамические) языки бы тем более позволили написать node.Tests вместо node[CONFIG_TESTS_SECTION].Children.Where(cn => cn.IsSameName(CONFIG_TEST_SECTION)).

                                            To chto tam napisan kod po injekzii dependencies — eto sdelano spezialno, no sut ne v etom

                                            В приведенном мной коде нет DI.

                                            mojno NFX zelikom t.k on UNISTACK.

                                            Нет, спасибо, не интересно, у меня уже есть фреймворк, женить два в одном проекте я не собираюсь.


  1. kekekeks
    29.07.2015 23:42

    Всё то же самое, но в более краткой записи и меньшим числом кода можно было сделать средствами JSON.NET. Ибо он умеет как грузить объекты по FQN, так и конвертить json-овские объекты в Dictionary<string, T>.


    1. itadapter
      29.07.2015 23:46
      -3

      what about macros? recursion detection? pluggable env vars rsolvers? reading constants right from code? structural merging of documents with override rules? tree comparisons, loading config files from any FileSystem (i.e. Git, SVN, Amazon, web etc..)? Is this what you are talking about?


      1. kekekeks
        29.07.2015 23:47

        Я в примерах выше перечисленного не вижу. И да, посмотрите в сторону такой штуки как HOCON. Скалисты очень активно используют, им нравится.


        1. itadapter
          29.07.2015 23:51
          -2

          youtu.be/reDvhz4RGhA
          It takes 60 minutes to describe the features of config WITHOUT going to details.
          How come config in .NET has 100+ data types yet it can not do SIMPLEST things like including a file from the web.
          If you have ever written anything yourself you know better what kind of pain it is to work with MS configuration.

          The lack of variables — the most rudimentary required thing, makes developers to put «mypath='c:\mydata\myfile'» 25 times in the same config.


          1. kekekeks
            29.07.2015 23:53

            Ну так не надо пользоваться System.Configuration. Она страшная и древняя. И таки посмотрите на HOCON. Реализацию на шарпе можно раздобыть в составе Akka.NET.


            1. itadapter
              29.07.2015 23:59
              -2

              i saw that. it still does not do (at least I did not find) many things that I need as of 2013 i.e.

              how can I include a file hosted on a DropBox account as one of my conf sub-nodes?
              how can i get a constant value from code in my config?
              how do i structurally merge sub-trees with injectable comparison functors?

              NFX conf existed back in 2003...sorry


              1. lair
                30.07.2015 00:02
                +1

                NFX conf existed back in 2003...

                И уже умело все описанное вами? Спустя год после выхода первого .net? За пять лет до появления дропбокса?


              1. kekekeks
                30.07.2015 00:04

                how can I include a file hosted on a DropBox account as one of my conf sub-nodes?
                NFX conf existed back in 2003...sorry
                Первый релиз дропбокса состоялся в 2008-ом году. Вам в 2003-ем таки удалось нормально собрать libastral, не иначе. А вообще HOCON умеет грузить куски конфигов из интернета. По остальным двум вопросам ничего не могу сказать, т. к. не возникала ни разу необходимость в подобном. По мержу можно подробнее посмотреть тут.


                1. itadapter
                  30.07.2015 00:10

                  This is irrelevant. In NFX we havd a concept of a FileSystem, back then I supported WEB and local.
                  Right now I know a guy uses DropBox.

                  An ability to include external files via an injectable file0system provider is a really awesome feature.
                  We use it in cluster, where config gets computed from pyramidal tiers of the system (similar idea as ms had with web.configs)
                  only we store evrything in SVN wih version control, so the whole clkuster definition is always versioned.

                  Vy ziplieetes k slovam ne vnikaja to chto vam po-delu otvechajut. (sorri za broken typing)


                  1. lair
                    30.07.2015 00:19

                    This is irrelevant. In NFX we havd a concept of a FileSystem, back then I supported WEB and local.

                    В HOCON есть включение через url(), никто не мешает сделаеть свой протокол с обработчиком. Реализация в akka.net вообще принимает делегат, который позволяет как угодно порезолвить включения.


                    1. itadapter
                      30.07.2015 00:22

                      right, and using C# one can write any software as long as C# runs on a Turing-complete vm :)

                      it is all about practicality. In windows you can easily map a «local drive» to some remote virtual FS. So what?
                      This is VERY far from being an integrated solution that works 99.9%, like we use SVNFIleSystem — it only has 300 lines of code
                      but guess what — it has never ever failed me.


                      1. lair
                        30.07.2015 00:27
                        +2

                        Что мне делать, если мне нужен не SVN, а Git? Я сильно выиграю от того, что у вас есть «концепция файловой системы»?

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


                        1. itadapter
                          30.07.2015 00:49

                          yes you will gain a lot, because nothing will change but 1 line in config:
                          _include{ file="/path/to/your/file" fx{ type=«NFX.IO.SVnFileSystem, NFX.Webl» params{...your connect strings..}}}

                          _include{ file="/path/to/your/file" fx{ type=«NFX.IO.GITFileSystem, NFX.GIT» params{...your connect strings..}}}

                          btw GIT is not in NFX oper source base, because it was needed only for one closed-source project where GIt is exclusive


                          1. lair
                            30.07.2015 00:54
                            +1

                            Разрабатывать эту «файловую систему» кто будет?

                            (Потому что с точки зрения самого конфиг-файла решение в hocon ничем не отличается: было include svn://path, стало include git://path)


                            1. itadapter
                              30.07.2015 00:56

                              Its already there for everything I need.
                              If you have XYZ file system then you need to implement it? no?
                              others will miraculously self-implement? HDFS? ACFS? GDrive?


                              1. lair
                                30.07.2015 01:00
                                +1

                                Я у вас про это и спрашиваю: в чем для меня выигрыш при реализации адаптера для нового хранилища, если сравнить вашу концепцию «файловой системы» и hocon-овский делегат?


                                1. itadapter
                                  30.07.2015 01:04
                                  +1

                                  v tom chto eto ispolzuetsya v desyatkax nest, takix kak ustanoivka programmnogo obespecheniya na servera.
                                  vy vse pytaetes dokazat chto u vas ne Unistack i vy s etim happy.
                                  Ya i ne spory

                                  u vas vyigrish budet togda kogda vy poimete chto pishete odno i tozhe 25 raz v kajdom proekete na 3x yazikax i 10 formatax… vot poka eto ne eknet v grudi — to NFX eto ujasniy framework ot kotorogo tolko odna golovnaja bol


                                  1. lair
                                    30.07.2015 12:28
                                    +1

                                    v tom chto eto ispolzuetsya v desyatkax nest, takix kak ustanoivka programmnogo obespecheniya na servera.

                                    Да какая мне разница, где это используется, мне мою задачу надо решить.

                                    vy vse pytaetes dokazat chto u vas ne Unistack i vy s etim happy.

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

                                    u vas vyigrish budet togda kogda vy poimete chto pishete odno i tozhe 25 raz v kajdom proekete na 3x yazikax i 10 formatax…

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

                                    Понимаете ли, беда обсуждаемого поста в том, что заголовок нам говорит про то, как конфигурация влияет на приложение, а сам пост — про то, как NFX влияет на приложение. Оставив в стороне вопрос, надо ли решать описанную задачу с помощью конфигурации, мы встаем перед вопросом: а что такого уникального в NFX для данной задачи, с чем не справились бы общепринятые решения?

                                    Ну да, System.Configuration для этого нездорово громоздок, с этим никто не спорит. Но любое другое решение, позволяющее сериализовать и прочитать граф, справится на ура. XML? Да (писать много буков, правда). JSON? Да. YAML? Да.

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

                                    foreach(var snode in node[CONFIG_SERIALIZERS_SECTION].Children.Where(cn => cn.IsSameName(CONFIG_SERIALIZER_SECTION)))
                                    {
                                      var item = FactoryUtils.Make<Serializer>(snode, args: new object[]{this, snode});
                                      m_Serializers.Register( item  );
                                    }
                                    


                1. itadapter
                  30.07.2015 00:15
                  +1

                  ya razve govoril chto HOCON ujasen? zamette, oni tozhe uzajut non-MS shit :)

                  no mne-to on zachem? I have tons of software written and running in production making money…
                  If you dont like NFX, thats fine…
                  however many people want to know the alternatives to MS stack.
                  HOCON is a good one, so is NFX


  1. shai_hulud
    30.07.2015 12:29
    +3

    Каждый пост про NFX превращается в срач между lair и адептами NFX.
    Причем настолько интересный, что статья уходит на второй план.

    У меня практичный вопрос, где-нибудь есть feature comparison table между NFX и ServiceStack? Имхо это две стороны одного велосипеда, и хочется узнать у какого из них звоночек громче.


    1. Leo_Gan Автор
      30.07.2015 18:45

      Насколько знаю, нет такого сравнения. Есть, к примеру, сравнение ServiceStack с WCF.
      Если по делу, то есть очень интересное видео про одно приложение NFX (для кэша, с какими-то сумасшедшими заявленными числами). Я сейчас как раз гоняю тесты из этого видео, (который на GitHub, лежит в WinFormsTest тесте).


      1. lair
        30.07.2015 18:57
        +1

        есть очень интересное видео про одно приложение NFX (для кэша, с какими-то сумасшедшими заявленными числами)

        Да про это и пост на хабре есть.


    1. itadapter
      31.07.2015 05:39

      ne dumaju chto takoi comparison nujen ili daje vozmojen. ServiceStack ochen malo imeet otnosheniya k NFX.
      Naprimer v NFX net ORM po opredeleniju — eto sovsem drugaja metodologiya.
      Ya ne sporju chto SrviceStack xorosho sdelanniy framework, esho est Castle, Lotka, NSpring i shtuk 10 drugix.
      Vse oni v chem to peresekautysa, gde-to rasxodyatsya.
      NFX voobshe tyt ne podxodit dlya sravneniya, on ne prednaznachen dlya «hire any 25 developers who know whats cool»
      V NFX net ni odnoi «cool» fishki, ni odnogo buzworda.
      Eto tem interesno kto ponimaet kak rabotaet motor vnutri