Получить целевой экземпляр IMessage из IServerChannelSink - PullRequest
0 голосов
/ 14 апреля 2020

Используя. NET удаленное взаимодействие между двумя процессами, я вставляю свой собственный приемник IServerChannel на стороне сервера, чтобы я мог перехватывать вызовы, инициированные клиентом, и перемещать их в соответствующий поток на сервере. В настоящее время я борюсь со способом преобразования Uri сообщения в экземпляр объекта сервера, чтобы я мог его проверить:

public ServerProcessing ProcessMessage(IServerChannelSinkStack sinkStack,
                                      IMessage requestMsg,
                                      ITransportHeaders requestHeaders,
                                      Stream requestStream,
                                      out IMessage responseMsg,
                                      out ITransportHeaders responseHeaders,
                                      out Stream responseStream)
{
  if (requestMsg is MethodCall methodCallMessage)
  {
    // how do I implement ConvertUriToObjectInstance to convert the Uri to a MarshallByRef instance???
    object instance = ConvertUriToObjectInstance(requestMsg.Uri);
  }
}

Есть ли способ преобразовать Uri в сервер созданный объект в фактический экземпляр MarshallByRef?

Я просмотрел пространство имен / класс System.Runtime.Remoting.Messaging, как в документации, так и через справочный источник, но я не вижу ничего, связанного с преобразованием Uri обратно в реальный экземпляр, который он представляет. Очевидно, что во время выполнения есть способ сделать это, но есть ли способ получить его, либо через официальный API, либо с помощью отражения?

Примечание Я знаю, что могу перейти потоки через что-то вроде ContextBoundObject, но я избегаю этого из-за его ограничений - как wrt generics.

1 Ответ

0 голосов
/ 14 апреля 2020

Глядя на реализацию ChannelServices.DispatchMessage, похоже, что он вызывает CheckDisconnectedOrCreateWellKnownObject, который возвращает ServerIdentity объект, содержащий свойство TPOrObject, которое кажется для преобразовать в экземпляр MarshalByRef.

Итак, следующий код отражения можно использовать для извлечения экземпляра из сообщения (проверка ошибок исключена):

private static MethodInfo CheckDisconnectedOrCreateWellKnownObject
  = typeof(ChannelServices).GetMethod(nameof(CheckDisconnectedOrCreateWellKnownObject), BindingFlags.Static | BindingFlags.NonPublic);

private static MethodInfo InstanceProperty
  = Type.GetType("System.Runtime.Remoting.Identity", true)
        .GetProperty("TPOrObject", BindingFlags.NonPublic | BindingFlags.Instance)
        .GetGetMethod(nonPublic: true);

private static object GetObjectInstance(IMessage methodCallMessage)
{
  var wellKnownObject = CheckDisconnectedOrCreateWellKnownObject.Invoke(null, new object[] { methodCallMessage });
  return InstanceProperty.Invoke(wellKnownObject, null);
}

Нет гарантии, если это всегда верно, однако.

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