Что такое моникер
От: Финченко Юрий  
Дата: 17.06.02 16:00
Оценка:
Вопрос номер два. А то у меня понятия стали путаться.

Что такое моникер?
Re: Что такое моникер
От: VVV Россия  
Дата: 17.06.02 16:29
Оценка:
Здравствуйте Финченко Юрий, Вы писали:

ФЮ>Вопрос номер два. А то у меня понятия стали путаться.


ФЮ>Что такое моникер?


вот тут пара примеров использования http://www.rsdn.ru/forum/message.asp?mid=12611
Автор: Gambler
Дата: 16.11.01
Что такое моникер
От: Vi2 Удмуртия http://www.adem.ru
Дата: 18.06.02 05:12
Оценка: 81 (11) +1
#Имя: FAQ.com.moniker
Здравствуйте Финченко Юрий, Вы писали:

ФЮ>Вопрос номер два. А то у меня понятия стали путаться.

ФЮ>Что такое моникер?

В любой объектно-ориентированной (ОО) системе полезно иметь способ идентификации конкретного экземпляра объекта. Эта идентификация (именование) в общем случае требует указания 2 элементов: способа создания объекта (эквивалентно заданию CLSID) и его перманентных данных (необязательно).

Сама по себе СОМ не предоставляет способа именования экземпляра объекта. В СОМ клиент может создать абстрактный экземпляр объекта, вызвав CoCreateInstance и передав её соответствующий CLSID. Если для объекта имеются перманентные данные, то клиент затем может использовать один из интерфейсов IPersist* или какой-то другой интерфейс, чтобы выдать объекту команду загрузки этих данных. Но для всех этих манипуляций клиент должен знать CLSID объекта и способ найти место хранения перманентных данных, а также иметь желание всё это проделать. В чистом виде СОМ не представляет клиенту простого решения. Однако существует помощник в этом деле, моникер, который и выполнит всю работу по созданию и инициализации конкретного экземпляра объекта.

Моникер — это имя определённого экземпляра объекта, имя одного конкретного сочетания некоторого CLSID и перманентных данных. Каждый моникер идентифицирует только один экземпляр объекта.

Но моникер — это больше чем просто имя. Он сам является СОМ-объектом, имеет свой способ создания и поддерживает особый интерфейс — IMoniker. У каждого моникера есть свои собственные перманентные данные, в составе которых всё, что
необходимо моникеру для запуска и инициализации одного экземпляра объекта, идентифицируемого этим моникером.

Зачем связываться с моникерами, что это нам даст? Так как клиенту в любом случае необходимо создавать СОМ-объект-моникер, почему просто не опустить этот этап вовсе и не создать целевой объект непосредственно? Зачастую моникер не даёт клиенту ничего: если создание моникера не уступает по сложности созданию и инициализации напрямую указываемого моникером объекта, эффект от применения моникера равен нулю. Но во многих других случаях (а их большинство!) моникеры могут значительно упростить жизнь клиента (и программиста, который пишет клиента!). Потому что, зная как вызывать IMoniker::BindToObject, клиент способен использовать моникеры для создания и инициализации объектов разных типов, каждый из которых может иметь абсолютно уникальные требования по созданию и инициализации. Инкапсуляция способов создания и инициализации объекта в моникере устраняет необходимость знания клиентом специфики процесса связывания и инициализации, так как, с точки зрения клиента, все моникеры выглядят одинаково.

Значит, если моникер является СОМ-объектом, то нам нужно знать моникер-2 на моникер-1, чтобы, создав моникер-1, можно было бы создать нужный нам экземпляр объекта? И где конец у этой последовательности? Возможно, но необязательно. Если клиент умеет создать один тип моникеров, то он может создавать через него много экземпляров других объектов. Также существует ряд стандартных моникеров, реализованных в системе и готовых к использованию. Существуют системные функции, дающие конкретные экземпляры моникеров.

В свою очередь, клиент может реализовать свой класс моникеров для идентификации объектов и создавать их в процессе работы по стандартным правилам СОМ.
Vita
Выше головы не прыгнешь, ниже земли не упадешь, дальше границы не убежишь! © КВН НГУ
Re[2]: Моникер - это Имя
От: Dima2  
Дата: 18.06.02 08:22
Оценка:
Здравствуйте Vi2, Вы писали:

Vi2>В любой объектно-ориентированной (ОО) системе полезно иметь способ идентификации конкретного экземпляра объекта. Эта идентификация (именование) в общем случае требует


Слушай напиши статью на эту тему, я думаю всем будет интересно, а то по поводу моникеров инфы мало и все как-то запутанно. Желательно с простыми жизненными примерами.
Re[3]: MkParseDisplayName - точка входа в моникеры
От: Vi2 Удмуртия http://www.adem.ru
Дата: 18.06.02 09:58
Оценка: 68 (7)
Здравствуйте Dima2, Вы писали:

D>Слушай напиши статью на эту тему, я думаю всем будет интересно, а то по поводу моникеров инфы мало и все как-то запутанно. Желательно с простыми жизненными примерами.


В моём случае "чукча — читатель, а не писатель" :))

А с моникерами и просто и сложно. Мы постоянно с ними сталкиваемся, и это такое открытие истины как то, что "мы все говорим прозой". Именования объектов происходит постоянно и независимо от нашего желания — так устроен человек: ему на все нужно навесить ярлычок (сиречь моникер) и работать уже дальше с ним как с данностью. Тут главное — соответствие ярлычок<->объект.

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

Когда мы превращаем строку ProgID-а "Project.Component" в реальный указатель, мы (или система) задействуем, фактически, некий (неявный или упрощённый) моникер-механизм, который и позволяет это делать — мы же не знаем реализации связывания имени с экземпляром, нас эти тонкости не интересуют. Здесь только нет перманентных данных, однако это можно легко исправить: "Project.Component?param1=value1?param2=value2?...?paramN=valueN;" строка вполне может идентифицировать проинициализированный объект.

Когда мы видим строку "C:\TMP\TMP.DOC", мы видим некий объект Word-а (определение CLSID) с данными из этого файла (перманентные данные). Это тоже отражение моникер-механизма, т.е. именования объектов.

Есть ещё один механизм, который сделан не в духе моникеров, хотя и пронизан этими идеями — получение от некоего Манагера объектов конкретного объекта через вызов метода Манагера и возврат указателя на интерфейс — различного рода Add(...id_объекта...) или Create(...id_объекта...), где число id_объекта может рассматриваться как другое, численное, представление строки id_объекта.

Пространство имён

Точно также как основную роль в СОМ выполняют CoCreateInstance|CoCreateInstanceEx, основную роль в пространстве имён выполняют функции MkParseDisplayName|MkParseDisplayNameEx, являющиеся точками входа в это пространство, переводящие имена в соответствующие моникеры. Есть, правда, и другие лазейки в это пространство, но гегемоны — это безусловно эти функции.

Опыт работы с моникерами и обобщение этого опыта приводят к обобщённому механизму именования объектов — в стиле URL — в форме ProgID:Name или @ProgID:Name (есть и дополнительные строки — имена файлов и т.д.). ProgID — это программный идентификатор первого моникера, создаваемого MkParseDisplayName, которому передётся вся строка для дальнейшего разбора. Вся последующая работа связана с функциями IMoniker::ParseDisplayName и IParseDisplayName::ParseDisplayName, которые и выполняют разбор строки.

Основные этапы работы с моникерами: у клиента есть (1) строка, идентифицирующая объект, которая передаётся функциям (2) MkParseDisplayName или MkParseDisplayNameEx для получения IMoniker* с последующим получением объекта через (3) IMoniker::BindToObject.

Дополнительно читайте в MSDN топик "MkParseDisplayName" и описания стандартных Моникеров системы "IMoniker-XXXX Implementation".
Vita
Выше головы не прыгнешь, ниже земли не упадешь, дальше границы не убежишь! © КВН НГУ
Re[4]: MkParseDisplayName - точка входа в моникеры
От: Dima2  
Дата: 18.06.02 13:06
Оценка:
Здравствуйте Vi2, Вы писали:

Ну, а говориш не писатель
Сюда бы подлить пару хороших примеров и все.
Re[5]: Примеры, хоть и поздно, но отпуск есть отпуск
От: Vi2 Удмуртия http://www.adem.ru
Дата: 24.07.02 06:17
Оценка: 57 (5)
Здравствуйте Dima2, Вы писали:

D>Сюда бы подлить пару хороших примеров и все.


Обнаружил файл, который подготавливал перед отпуском.

По аналогии с хорошо известным механизмом создания объекта через CoCreateInstance (без агрегации)
Псевдо-код для                                          Псевдо-код для
  MkCreateInstance(<TEXT>,<IID_Ix>,<ppObj>)               CoCreateInstance(<CLSID>,NULL,<Context>,<IID_Ix>,<ppObj>)

CComPtr<IMoniker> pmk;                                  CComPtr<IClassFactory> pcf; 
ULONG chEaten;
CComPtr<IBindCtx> pbc;
hr = CreateBindCtx(0,&pbc);

hr = MkParseDisplayName(pbc,<TEXT>,&chEaten,&pmk);      hr = CoGetClassObject(<CLSID>,<Context>,NULL,__uuidof(*pcf),&pcf);
if( SUCCEEDED(hr) )                                     if( SUCCEEDED(hr) )
  hr = pmk->BindToObject(pbc,NULL,<IID_Ix>,<ppObj> );     hr = pcf->CreateInstance(NULL,<IID_Ix>,<ppObj> );
if( SUCCEEDED(hr) )                                     if( SUCCEEDED(hr) )
  объект создан и проинициализирован данными              объект создан с данными по умолчанию

Вызов псевдо-кода                                       Вызов псевдо-кода
MkCreateInstance(TEXT_x,IID_Ix,ppObj);                  CoCreateInstance(CLSID_x,NULL,CLSCTX_ALL,IID_Ix,ppObj);

Можно "колбасить" вокруг контекста pbc, задавая различные способы связывания, или использовать объект-моникер как объект-классфактори для создания нескольких объектов (а не одного, как в примере) или для асинхронного связывания (в примере код будет остановлен до завершения BindToObject).

Как создавать свои Моникеры:

Предположим, Вы хотите реализовать некое имя "ваше_имя", которое позволит другим клиентам использовать моникер
"ваше_имя:данные_в_вашем_формате" для идентификации объектов в Вашем пространстве имён. Для этого нужно реализовать
интерфейс IParseDisplayName или в фабрике класса, или в самом объекте и зарегистрировать это имя в Реестре в
HKEY_CLASSES_ROOT\ваше_имя с подключом CLSID (т.е. это обычный ProgID). Во время разбора имени MkParseDisplayName
находит слово "ваше_имя" в Реестре, получает его CLSID и обращается за интерфейсом IParseDisplayName, как я указал выше.
Если такой интерфейс не нашёлся, то разбор оканчивается неудачей. Если нашёлся, то вызывается
IParseDisplayName::ParseDisplayName, тем самым вся дальнейшая обработка осуществляется Вашим объектом.
Vita
Выше головы не прыгнешь, ниже земли не упадешь, дальше границы не убежишь! © КВН НГУ
Re[6]: CoGetObject
От: Vi2 Удмуртия http://www.adem.ru
Дата: 29.07.02 07:00
Оценка: 27 (2)
Vi2>Вызов псевдо-кода
Vi2>MkCreateInstance(TEXT_x,IID_Ix,ppObj);

Оказывается есть уже такая функция для MkCreateInstance!
И называется CoGetObject и работает примерно по тому алгоритму, как и псевдо-код из предыдущего письма:
WINOLEAPI CoGetObject(LPCWSTR pszName,BIND_OPTS *pBindOptions,REFIID riid,void **ppv);

Правда, передача в неё ProgID-а обычного СОМ объекта заканчивается неудачей, но это понятно — всё же это не моникер.

Однако, могли бы господа из MS сделать и такой вход — тогда цены бы ей не было, и CoCreateInstance была бы альтернатива.

PS

Ещё один пример моникеров в статье Don Box MSJ &mdash; июль 1997 года, посвященной, кстати, очень актуальной теме 1)Конструирование СОМ объектов конструкторами с параметрами, а также 2) Синглетоны, в частности, задаваемые моникерами.

Синглетоны, рассмтариваемые Don Box, — это объекты, представляющие время на сервере. Причём, позволяющие учитывать смещение времени в клиенте простым изменением моникера объекта и без изменения кода клиента. А также перенаправлять на другой сервер, опять же изменением моникера.
Vita
Выше головы не прыгнешь, ниже земли не упадешь, дальше границы не убежишь! © КВН НГУ
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.