Пытаюсь подставить свою проксю, которая бы работала во всех возможных режимах в зависимости от предпочтений клиента. Т.е. не только только в локальном режиме или только в сетевом, а в любом в котором захочет клиент.
Пытаюсь передать управление стандартной RemotingProxy, но получаю облом в выделенной строке.
using System;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Services;
using System.Runtime.Remoting.Proxies;
using System.Runtime.Remoting.Messaging;
using System.Runtime.Remoting.Activation;
namespace TestObject
{
class TestProxy : RealProxy
{
MarshalByRefObject obj;
public TestProxy(Type type,MarshalByRefObject o)
: base(type)
{
obj = o;
}
public override IMessage Invoke(IMessage msg)
{
RealProxy rp = RemotingServices.GetRealProxy(obj);
return rp.Invoke(msg);
}
}
[AttributeUsage(AttributeTargets.Class)]
public class TestProxyAttribute: ProxyAttribute
{
public override MarshalByRefObject CreateInstance(Type type)
{
MarshalByRefObject obj = base.CreateInstance(type);
TestProxy rp = new TestProxy(typeof(Test),obj);
return (MarshalByRefObject)rp.GetTransparentProxy();
}
}
[TestProxy]
public class Test: ContextBoundObject
{
public Test()
{
}
public string GetAppName()
{
return AppDomain.CurrentDomain.FriendlyName;
}
}
}
Как бы это дело забороть?
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте, AndrewVK, Вы писали:
AVK>А облом то какой?
Вот такой:
Unhandled Exception: System.NullReferenceException: Object reference not set to an instance of an object.
at System.Runtime.Remoting.Messaging.ClientContextTerminatorSink.SyncProcessMessage(IMessage reqMsg)
at System.Runtime.Remoting.Activation.ActivationServices.Activate(RemotingProxy remProxy, IConstructionCallMessage ctorMsg)
at System.Runtime.Remoting.Proxies.RemotingProxy.Invoke(IMessage reqMsg)
at TestObject.TestProxy.Invoke(IMessage msg) in c:\it\remin\testobject\testobject.cs:line 33
at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
at TestObject.Test..ctor() in c:\it\remin\testobject\testobject.cs:line 98
at Client.Client.Main(String[] args) in c:\it\remin\client\client.cs:line 14
Если убираю свой прокси, т.е. делаю так:
[AttributeUsage(AttributeTargets.Class)]
public class TestProxyAttribute: ProxyAttribute
{
public override MarshalByRefObject CreateInstance(Type type)
{
MarshalByRefObject obj = base.CreateInstance(type);
return obj;
}
}
То работает. Естественно, перехвата не происходит.
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте, AndrewVK, Вы писали:
IT>>То работает. Естественно, перехвата не происходит.
AVK>Может из=за того что ты CreateProxy() у атрибута не перекрыл?
Он всё равно ещё не вызывается
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте, AndrewVK, Вы писали:
AVK>А что вобще за фраза такая что CreateInstance возвращает либо marshalbyref неинициализированный либо прозрачную прокси в зависимости от типа?
Возвращает прозрачную проксю.
Вообще-то, я хочу сделать проксю, которая бы работала в локальном режиме и при ремотинге как на клиенте, так и на сервере. Но вот что-то пока ни как
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте IT, Вы писали:
IT>Возвращает прозрачную проксю. IT>Вообще-то, я хочу сделать проксю, которая бы работала в локальном режиме и при ремотинге как на клиенте, так и на сервере. Но вот что-то пока ни как
A real object can be called from the overridden Invoke by calling RemotingServices.ExecuteMessage, which is used to dispatch the call onto the real object.
Здравствуйте, AndrewVK, Вы писали:
AVK>A real object can be called from the overridden Invoke by calling RemotingServices.ExecuteMessage, which is used to dispatch the call onto the real object.
Я пока затыкаюсь на конструировании объекта, до этого ещё не дошёл
Если объект создавать не через new, а в явную создавать прокси для уже созданного экземпляра, то вроде тоже всё понятно.
Ладно, буду копать дальше. Если чего найдёшь, дай мне знать
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте, IT, Вы писали:
IT>Здравствуйте, AndrewVK, Вы писали:
AVK>>A real object can be called from the overridden Invoke by calling RemotingServices.ExecuteMessage, which is used to dispatch the call onto the real object.
IT>Я пока затыкаюсь на конструировании объекта, до этого ещё не дошёл
Здравствуйте IT, Вы писали:
Сделал по примеру из книги и .. еще возможность асинхронности вызовов.
Список классов:
1. TestProxyProperty
2. TestProxyAttribute
3. TestMessage
4. AsyncReplyHelperSink
5. TestProxy
6. Test
using System;
using System.Runtime.Remoting.Proxies;
using System.Runtime.Remoting.Contexts;
using System.Runtime.Remoting.Activation;
namespace TestObject
{
[AttributeUsage(AttributeTargets.Class)]
public class TestProxyProperty: Attribute, IContextProperty
{
public void Freeze(
Context newContext)
{
}
public bool IsNewContextOK(
Context newContext)
{
return true;
}
public string Name
{
get
{
return"TestProxyProperty";
}
}
}
}
using System;
using System.Runtime.Remoting.Proxies;
using System.Runtime.Remoting.Contexts;
using System.Runtime.Remoting.Activation;
namespace TestObject
{
[AttributeUsage(AttributeTargets.Class)]
public class TestProxyAttribute: Attribute, IContextAttribute
{
public bool IsContextOK(
Context context,
IConstructionCallMessage msg)
{
return false;
}
public void GetPropertiesForNewContext(
IConstructionCallMessage msg)
{
msg.ContextProperties.Add(new TestProxyProperty());
}
}
}
using System;
using System.Runtime.Remoting.Messaging;
namespace TestObject
{
public class TestMessage: IMessageSink
{
IMessageSink _nextSink;
public TestMessage(
IMessageSink nextSink)
{
_nextSink = nextSink;
}
public IMessageSink NextSink
{
get
{
return _nextSink;
}
}
public virtual IMessage SyncProcessMessage(
IMessage msg)
{
try
{
return _nextSink.SyncProcessMessage(msg);
}
catch(Exception ex)
{
return new ReturnMessage(ex, (IMethodCallMessage)msg);
}
}
public virtual IMessageCtrl AsyncProcessMessage(
IMessage msg,
IMessageSink replySink)
{
try
{
AsyncReplyHelperSink.AsyncReplyHelperSinkDelegate sinkDelegate =
new AsyncReplyHelperSink.AsyncReplyHelperSinkDelegate(
this.AsyncProcessReplyMessage);
replySink = (IMessageSink) new AsyncReplyHelperSink(
replySink, sinkDelegate);
return _nextSink.AsyncProcessMessage(msg, replySink);
}
catch
{
return null;
}
}
public IMessage AsyncProcessReplyMessage(
IMessage msg)
{
return msg;
}
}
}
using System;
using System.Runtime.Remoting.Messaging;
namespace TestObject
{
public class AsyncReplyHelperSink: IMessageSink
{
public delegate IMessage AsyncReplyHelperSinkDelegate(
IMessage msg);
IMessageSink _nextSink;
AsyncReplyHelperSinkDelegate _sinkDelegate;
public AsyncReplyHelperSink(
IMessageSink nextSink,
AsyncReplyHelperSinkDelegate sinkDelegate)
{
_nextSink = nextSink;
_sinkDelegate = sinkDelegate;
}
public IMessageSink NextSink
{
get
{
return _nextSink;
}
}
public virtual IMessage SyncProcessMessage(
IMessage msg)
{
if(_sinkDelegate != null)
{
IMessage msg2 = _sinkDelegate(msg);
return _nextSink.SyncProcessMessage(msg2);
}
else
{
return new ReturnMessage(
new Exception(
"AsyncProcessMessage _sinkDelegate member is null!"),
(IMethodCallMessage)msg);
}
}
public virtual IMessageCtrl AsyncProcessMessage(
IMessage msg,
IMessageSink replySink)
{
return null;
}
}
}
using System;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Proxies;
using System.Runtime.Remoting.Messaging;
namespace TestObject
{
class TestProxy: RealProxy
{
MarshalByRefObject obj;
public TestProxy(
Type type,
MarshalByRefObject o
): base(type)
{
obj = o;
}
public override IMessage Invoke(
IMessage msg
)
{
RealProxy rp = RemotingServices.GetRealProxy(obj);
return rp.Invoke(msg);
}
}
}
using System;
namespace TestObject
{
[TestProxy]
public class Test: ContextBoundObject
{
public Test()
{
}
public string GetAppName()
{
return AppDomain.CurrentDomain.FriendlyName;
}
}
}
Здравствуйте, kreek, Вы писали:
K>Здравствуйте IT, Вы писали: K>Сделал по примеру из книги и .. еще возможность асинхронности вызовов. K>Список классов: K>1. TestProxyProperty K>2. TestProxyAttribute K>3. TestMessage K>4. AsyncReplyHelperSink K>5. TestProxy K>6. Test K>Надеюсь, не сочтете за оверквотинг
Может это и глупый вопрос, но где используется класс TestProxy? И что показывает данный пример?
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.
Здравствуйте TK, Вы писали:
TK>Может это и глупый вопрос, но где используется класс TestProxy? И что показывает данный пример?
Черт, лажанулся IContextAttribute не имеет интерфейсного метода CreateInstance, а ProxyAttribute не декларирует методы IContextAttribute виртуальными, т.е. сорри, поспешил.
Здравствуйте, IT, Вы писали:
IT>Здравствуйте, AndrewVK, Вы писали:
AVK>>A real object can be called from the overridden Invoke by calling RemotingServices.ExecuteMessage, which is used to dispatch the call onto the real object.
IT>Я пока затыкаюсь на конструировании объекта, до этого ещё не дошёл
Это-то легко. rp.InitializeServerObject. Гораздо интереснее то, что Две прокси на один объект иметь нельзя
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.
Здравствуйте, IT, Вы писали:
IT>Пытаюсь передать управление стандартной RemotingProxy, но получаю облом в выделенной строке.
IT> public override IMessage Invoke(IMessage msg) IT> { IT> RealProxy rp = RemotingServices.GetRealProxy(obj); IT> return rp.Invoke(msg); IT> } IT> }
IT>.. IT>Как бы это дело забороть?
В TestProxy.Invoke приходят два вида msg. Первый для конструирования, второй для вызовов методов.
Msg для конструктора нельзя передавать во внутрений объект (он уже сконструирован).
Попробуй добавить в Invoke:
public override IMessage Invoke(IMessage msg)
{
RealProxy rp = RemotingServices.GetRealProxy(obj);
IConstructionCallMessage ccm=msg as IConstructionCallMessage;
if(ccm!=null)
return EnterpriseServicesHelper.CreateConstructionReturnMessage(
ccm,
(MarshalByRefObject) this.GetTransparentProxy()
) ;
else
return rp.Invoke(msg);
}
Здравствуйте, kreek, Вы писали:
K>Здравствуйте Silver_s, Вы писали:
K>Первое сообщение проходит, а на второе ругается: K>Trying to call proxy while constructor call is in progress.
А объект кто-нибудь конструировать будет? RealProxy ждет, что сейчас ему придет CCM, а вы ему MCM подсовываете. Он даже не знает кому его направить...
Вызов EnterpriseServicesHelper.CreateConstructionReturnMessage это не совсем то.
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.
Это я конечно смотрел и вашу дискуссию с Сильвером читал.
В твоём примере объект создаётся локально всегда, даже если в конфиге он прописан удалённо. В принципе это тоже интересный вариант и возможно пригодится.
Пока я прихожу к выводу, что нужно всё таки знать где создаётся объект, на клиенте или на сервере. При чём желательно это определить ещё до создания самого объекта по его типу.
Если нам не помогут, то мы тоже никого не пощадим.