То, что называется MessageAgent, доступно для managed code через Microsoft.BizTalk.Interop.Agent.dll. Так же называется и соответствующий namespace. Подключились? Создаем MessageAgent:
IBTMessageAgent agent=
new BTMessageAgent() as IBTMessageAgent;
Тут же присоединяем его к MessageBox:
agent.SetConfigDbLocation(<server name>, "BizTalkMgmtDb");
Понятно, что account, с которого испоняется этот код должен быть членом группы 'BizTalk Server Administrators'. Некоторые пояснения, которые могут показаться излишними для тех, кто уже попробовал устанавливать удаленные адаптеры, подключать BizTalk к удаленной базе и т.д. : сам по себе BizTalk Server (в частности, его EPM) не имеет непосредственно дело с базой; в этом и состоит, собственно, задача MessageAgent, т.е. в BizTalk группе может быть много агентов, разговаривающих с одной и той же базой - MessageBox. Между собой они могут даже не познакомиться - каждый будет действовать отдельно. Именно отсюда, кстати, возникает абсудрность идеи создать BizTalk Server cluster, и с другой стороны, обоснованность создания cluster для SQLServers, на кот. установлен MessageBox.
Итак, MessageAgent создан и подключен к базе. Теперь нам понадобится второй assembly - Microsoft.XLANGs.BizTalk.Engine ( не путать с Microsoft.XLANGs.Engine.dll ). Из него нам нужно получить некоторый GUID, с которым связан MessageAgent. Вернее, не MessageAgent itself, а его XLANGs SubService. Этот GUID будет использоваться в следующем вызове, регистрирующем newly created MessageAgent в XLANGs SubService:
agent.RegisterService(
ref agentGUID, null);
Задачей MessageAgent является запись сообщений в базу, не так ли? Но, во-первых, эти сообщения поступают в базу "завернутыми" в batch (который, естественно, может состоять и из только одного сообщения), а во-вторых, эта процедура записи сообщений проводится в помощью еще одной абстракции, под именем MessageSpace(Ex). В задачу MessageSpace входит генерация уникального GUID для каждого batch. За один шаг до самой записи сообщения, подготовка к нему выглядит, таким образом:
IBTMessageSpace sp = agent.RegisterAsPublisher("BizTalk Group", "msgAgent");
IBTMessageSpaceEx spx = (IBTMessageSpaceEx)sp;
Guid spuid= Guid.Empty;
IBTMessageBatch expex = sp.GetMessageBatch(ref spuid);
Чтобы продвигаться дальше нам потребуется 3-й assembly - Microsotf.BizTalk.Pipeline. Именно в нем находится тот интерфейс, с помощью которого на свет рождаются сообщения - IBTMessageAgentFactory со своим методом CreateMessage(). Довольно логично, но вот только никак не выражено в определении самого интерфейса, что из MessageAgent можно добраться до его MessageFactory. Трюк состоит в следующем приведении:
IBTMessageAgentFactory msgfactory = (IBTMessageAgentFactory)agent;
Ну, теперь поднимем тост за новорожденного:
IBTMessage msg= (IBTMessage)msgfactory.CreateMessage();
Правда, первоначально родилось не совсем то, что ожидали - IBaseMessage, но мы его же его тут же и преобразовали; так что никто ничего не заметил. (А для педантов, я еще вернусь к этому знаменательномы событию).
Нашими ближайшими целями отныне станут 2 метода из MessageSpace - 1). PostMessages() и CommitBatch(). Первый ознаменует собой просто запись сообшения в базу, без намерений его обрабатывать. Второй - скажет DrafonFly (или попросту - Pub/Sub evaluation) , что все сообщения из конкретного batch прочно записаны и пришло время их обработать, в поисках ожидающего сервиса (orchestration обычно). PostMessages() не представляет большой проблемы. Художественная подготовка к нему будет состоять в том, чтобы установить message context и сделать promotion на те из его properties , кот. мы счиатем необходимыми. Установка context:
msg.Context.Write("MessageType",
"http://schemas.microsoft.com/BizTalk/2003/system-properties",
"Microsoft.BizTalk.XLANGs.BTXEngine.ExecMessage");
msg.Context.Write("MessageType",
msg.Context.Write("ActivationServiceID",
msg.Context.Write("ActivationServiceID", "http://schemas.microsoft.com/BizTalk/2003/system-properties",
"My Orchestration full name");
Лично мне не очень нравится такая художественная подготовка - Orchestration full name мешает. С другой стороны, надо же знать, кого вызываешь!
Теперь promotion:
msg.Context.Promote("MessageType", "http://schemas.microsoft.com/BizTalk/2003/system-properties",
"Microsoft.BizTalk.XLANGs.BTXEngine.ExecMessage");