Re: Свой RealProxy
От: msl Россия  
Дата: 17.07.03 09:52
Оценка:
Здравствуйте, Maxeemus, Вы писали:

M>Здравствуйте все.

M>Не подскажите как подменить стандартный RealProxy своим на клиенте, если на клиенте удаленный объект доступен только через интерфейсы.
M>Но не так:
M>
M>   IRemoteObj robj = (IRemoteObj) (new MyRealProxy(typeof(IRemoteObj)).GetTransparentProxy());
M>

M>Потому что клиента менять не хочется.
M>Пытался сделать это через свой ProxyAttribute, но RealProxy подменяеться только на сервере.
M>Это логично, так как атрибут применен для класса, который на только на сервере.
M>Заранее спасибо.


Не знаю, актуально ли для Вас данная проблема.
Но тем не менее я решил написать, как решил ее я.

Существует два способа создания реального прокси:
— атрибут
— код, наподобие этого:

   ISomeActivator   activator = (ISomeActivator)Activator.GetObject(type, "tcp://localhost:8080/Server");
   ServerObjProxy   newProxy = new ServerObjProxy(typeof(ISomeActivator), (MarshalByRefObject)activator);
   activator = (ISomeActivator)newProxy.GetTransparentProxy();


1-й способ влечет за собой активацию кода атрибута и в случае, когда объект создается в серверном процессе для "собственных нужд". Кроме того, атрибуты работают (если я правильно понял) только для конструкций типа "new QQQ" или "Activator.GetObject". При передаче по ссылке оно на клиенте не работает.

Отсюда можно сделать вывод, что нужно использовать 2-й способ. Ну а чтобы не городить код создания прокси постоянно, я сделал так:

Сделал для своего активатора объектов прокси, в котором есть вот такая ф-ция Invoke (правда она предназначена только для ф-ций типа IQQQ GetInterface() ):


public    override IMessage     Invoke(IMessage msg)
{
    // сначала обработаем запрос...
    IMessage    retMsg = m_OldRProxy.Invoke(msg);
    Object        retValue;

    // мы поддерживаем этот интерфейс?
    if (retMsg is IMethodReturnMessage)
    {
        IMethodReturnMessage    mrm = (IMethodReturnMessage)retMsg;
        retValue = mrm.ReturnValue;
        // может быть, результат - прозрачное прокси
        if (RemotingServices.IsTransparentProxy(retValue))
        {
            // получим тип возвращаемого объекта...
            Type            typeCurObject = Type.GetType(mrm.TypeName);
            // рассматриваем только методы без параметров, возвращающие интерфейс
            MethodInfo        methodInfo = typeCurObject.GetMethod(mrm.MethodName, new Type[0]);

            ServerObjProxy    newProxy = new ServerObjProxy(methodInfo.ReturnType, (MarshalByRefObject)retValue);
            ReturnMessage    returnMessage = new ReturnMessage(newProxy.GetTransparentProxy(), mrm.OutArgs, mrm.OutArgCount,
                mrm.LogicalCallContext, (IMethodCallMessage)msg);
            return returnMessage;
        }
    }
    return retMsg;
}
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.