Reputation: 6903
I have a class which needs to behave differently when being called remotely via .Net remoting. How can I determine, inside the class, if this is the case?
class RemoteClass : MarshalByRefObject
{
public void SomeMethod ()
{
if (ConditionWhatINeed) //If this method was called internally/remotely
{
//Do one stuff
}
else
{
//Do another suff
}
}
Upvotes: 3
Views: 384
Reputation: 9228
There may be a way using one of the *Services
objects under the System.Runtime.Remoting
hierarchy, as mtijn indicated. However, you have deep problems in your object model. Having dual responsibility on objects is bad practice, difficult to maintain and difficult to understand. Why not rather expose a dedicated 'remote' object; the following sample demonstrates it:
class Program
{
static void Main(string[] args)
{
InitializeRemoting();
var remote = GetRemotingObject("localhost");
var local = new LocalClass();
remote.SomeMethod();
local.SomeMethod();
Console.ReadLine();
}
static void InitializeRemoting()
{
var c = new TcpServerChannel(9000);
ChannelServices.RegisterChannel(c, false);
WellKnownServiceTypeEntry entry = new WellKnownServiceTypeEntry
(
typeof(RemoteClass),
"LocalClass", // Lie about the object name.
WellKnownObjectMode.Singleton
);
RemotingConfiguration.RegisterWellKnownServiceType(entry);
}
static LocalClass GetRemotingObject(string serverName)
{
TcpClientChannel channel = new TcpClientChannel("tcp-client", new BinaryClientFormatterSinkProvider());
ChannelServices.RegisterChannel(channel, false);
return (LocalClass)Activator.GetObject
(
typeof(LocalClass), // Remoting will happily cast it to a type we have access to.
string.Format("tcp://{0}:9000/LocalClass", serverName)
);
}
}
public class LocalClass : MarshalByRefObject
{
public void SomeMethod()
{
OnSomeMethod();
}
protected virtual void OnSomeMethod()
{
// Method called locally.
Console.WriteLine("Local!");
}
}
// Note that we don't need to (and probably shouldn't) expose the remoting type publicly.
class RemoteClass : LocalClass
{
protected override void OnSomeMethod()
{
// Method called remotely.
Console.WriteLine("Remote!");
}
}
// Output:
// Remote!
// Local!
Edit: To answer your question directly, even though what you are trying to achieve is bad practice, duplicate my code and simply provide a virtual bool IsLocal { get { return true; } }
on the local class and override it on the remote class. You can then use the property in your if statements.
Edit: If you server and your clients needs to share the exact same instance of the class you should use the Facade Pattern. For example:
class CommonImplementation
{
public static readonly CommonImplementation Instance = new CommonImplementation();
private CommonImplementation() { }
public void SomeMethod(string someArg, bool isServerCall)
{
if (isServerCall)
{
Console.WriteLine("Remote! {0}", someArg);
}
else
{
Console.WriteLine("Local! {0}", someArg);
}
}
}
// These two classes are the facade.
public class LocalClass : MarshalByRefObject
{
public virtual void SomeMethod(string someArg)
{
CommonImplementation.Instance.SomeMethod(someArg, false);
}
}
class RemoteClass : LocalClass
{
public override void SomeMethod(string someArg)
{
CommonImplementation.Instance.SomeMethod(someArg, true);
}
}
Upvotes: 1
Reputation: 3678
you may want to have a look at the RemotingServices.IsObjectOutOfContext Method. it also has an example you may find useful. of course, because you'll be calling this method server-side on 'this' it will never be seen as a remoting object but if you add a parameter to your method than that parameter will be in local context if not remoting and out of context when remoting (PS this is an unverified assumption on my account). Another useful helper may be the RemotingServices.IsTransparentProxy Method.
Upvotes: 1