Здравствуйте, 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;
}