What's the purpose for MarshalByRefObject?
Remoting; it means that between AppDomains or machines, rather than serialize and transfer the object, the object stays at one end and a proxy is created at the other. All method calls to the proxy are intercepted and the call is transmitted as RPC wiki, msdn, causing the method to execute on the other machine (typically serialising the arguments and return value).
Note: this can lead to unexpectedly "chatty" interfaces. The object/proxy/RPC approach is now less preferable to approaches with an explicit service boundary; Microsoft now recommends WCF wiki, msdn instead of remoting.
Another important use of MarshalByRefObject is for implementing AOP via remoting sink-chains.
If you have an object that derives from ContextBoundObject (which itself derives from MarshalByRefObject) you can instantiate it in a separate Context within the same AppDomain and have communications between objects automatically go through the Remoting proxy system - allowing you to plug custom sinks into the Remoting sink-chain.
This ultimately allows you to 'decorate' method calls to your objects and implement cross-cutting services, such as logging and security etc.
it basic use is for support access of objects between two appdomains and these appdomains can be on the same computer or in the different computers via remoting.
See Here
Any object outside the application domain of the caller application should be considered as Remote Object. A Remote Object that should be derived from MarshalByRefObject Class. Any object can be changed into a Remote Object by deriving it from MarshalByRefObject. Objects without inheriting from MarshalByRefObject are called Non-remotable Objects.
Related
In the wcf duplex project I am working on, proxy is created and opened using the following 3 lines:
InstanceContext context = new InstanceContext(new MyCallbackObjectImplementingCallbackContract());
_proxy = new ServiceClient(context);
_proxy.Open();
I have a couple of questions here:
Lets say my callback contract has just 3 methods(operation contract) and on my callback class, on top of just implementing those 3 I have like 10 more methods.
I found by debugging on server side when
OperationContext.Current.GetCallbackChannel<IMyCallbackContract>() is called
the object returned has only the methods with attribute 'OperationContract', and not the whole object. What is the magic behind the scenes. Also, is it not a bad design to have bunch of extra(not contract implementations) methods on call back class, if so what impact could it possibly have?
_proxy.open() metadata says object to transition from the created state into the opened state. I don't quite get what that means?
Question #1: Yes, WCF only looks for methods marked with OperationContract attribute. It creates proxies using the old Remoting RealProxy/TransparentProxy mechanism. Basically, WCF looks for operations in the contract interface, not in a class that implements the interface. It also proxies the contract interface, and not an implementation class.
As for the design question, it depends. As long as the other methods help the operation methods fulfill their contract, there is no problem. But if the other methods implement a different responsibility, then as it sounds, such design violates the single responsibility principle.
Question #2: in WCF, channel proxies inherit CommunicationObject. This object is not stateless, it tracks state of communication over the channel. Moreover, it can hold a session on the remote side, which is an expensive and limited resource. For these reasons, communication object should be treated much like database connection: open it, execute the operation, then Close() or Abort(). You can find more details in this MSDN topic.
I have a interface (let name it OuterInt) and a class (OuterClass) that implemented It. Interface OuterInt consists of the other intefaces (InnerInt1, InnerInt2 and etc.) And there are some classes (InnerClass1, InnerClass2 and etc.) that implement these inner interfaces. OuterClass is exposed by server-side of application by .NET remoting (RemotingServices.Marshal(_OuterClass, "myOuterInt");)
My question is will inner classes be serialized in the process of remoting or not and should client-side of application knows about those classes (for example to have reference of assembly with these classes)? I hope that I described my question explicitly, if not - ask me in comments.
Remoting (which is, as Oded notes, pretty much deprecated) creates a remote hook to the object; not the API (the interface). As such, it will indeed be necessary to have the same dll (containing the concrete type being remoted) at both ends. Whether it is serialized vs proxied depends on whether it inherits from MarshalByRefObject. But typically: if it is in the object graph at one end, then it needs to be creatable at the other.
If possible, prefer virtually any other implementation to remoting, IMO.
In my Azure web role code I have a CustomIdentity class derived from System.Security.Principal.IIdentity. At some point .NET runtime tries to serialize that class and serialization wouldn't work. Trying to resolve that I searched a lot and found this answer and tried to inherit my class from MarshalByRefObject.
Now once my CustomIdentity class inherits from MarshalByRefObject there're no serialization attempts anymore and my code works. However I'd like to know the performance implications of using MarshalByRefObject class.
My code runs like this. First the request comes to IIS and is passed to the authentication code that creates an instance of CustomIdentity and attaches that instance to HTTP context. Then some time later the same HTTP context is passed to the ASP.NET handler that accesses that CustomIdentity instance at most once. The CustomIdentity object lives for the duration of request and is then destroyed.
Now with serialization my CustomIdentity would be serialized into a stream, then deserialized from that stream into a new object. With MarshalByRefObject there's no serialization but a proxy is created and the access will be marshaled via RPC to where the actual object resides.
How expensive will using MarshalByRefObject be in this scenario? Which - MarshalByRefObject or serialization - will be more costly?
MarshalByRefObject means that all calls (methods, properties, etc) are proxied over the wire. This potentially means that instead of transferring the data once and then running multiple methods etc locally on the transferred data, you are making a network call every access. How many times (per request) is a role tested, for example? or the name queried? I honestly don't know, but I'm guessing it is more than 1 (all totalled). Plus the original setup costs...
The bandwidth probably won't be significant, but latency is very significant, especially if you have distributed nodes (since you mention a cloud scenario).
Personally, I would avoid MarshalByRefObject like the plague, but up to you...
I have some member functions in three custom classes already created in my service. My objective is to use these custom classes on the client side to access the the member functions in the service. How do I expose these classes with all the member methods in them to the client?
I created these three classes in my service and marked them as "DataContract", and the member functions as "OperationContract". I created an Interface that defines these custom classes as OperationContracts returning an object of each of the classes through implementing them on a separate class.
Unfortunately, I couldn't achieve my objective because two of the classes have a constructor that takes some parameters, whereas the class with no constructor was accessible on the client side but I couldn't see the member methods in the class.
I need your hints on what to do.
That won't be easy to do. One way would be to share the DataContract-decorated types between the WCF server and its clients, i.e. add a reference to your service assembly in the client project and bind the service reference to that assembly reference.
However, that breaks contract implementation independence, as the exact same service assembly will need to exist on both the client and the server, and be kept synchronized every time it changes.
See here for more details.
By default and by design, WCF will only share contracts between client and server, e.g. your services ([ServiceContract]), their methods ([OperationContract]) and the data structures they operate on ([DataContract]).
WCF is a message passing system, so all the client and the server share in terms of the data being passed around is a XML serialized message format. When you add a service reference, the client-side proxy will generate a class for each [DataContract] that will look identical in XML serialized format - only the data is being moved back and forth - no behavior (no methods).
Basically, if you want to expose functionality, you need to have a service method decorated with a [OperationContract] attribute. Methods on your data classes will never be visible to the client - and that's by design.
If you control both ends of the communication and both are .NET based, you can "trick" your way around this limitation:
put all your service and data contracts into a separate class library assembly
use a reference to that common, shared assembly to create your service
before you do an Add Service Reference, add a reference to that common assembly on your client
In that case, the WCF runtime will reuse existing types from that common assembly, instead of re-creating them from the service description. And since that assembly contains the shared code that the server also uses, your classes also have their methods present.
It works ok in a .NET only scenario, but it's really kind of a dirty trick behind the proper service separation facade.
I am developing an .net application which heavely depends on plugins. The application itself contains an connection to a remote server.
Recently I digged into Application domains and see them as the ideal solution for isolating the plugin code from the rest of the application.
However there is one big disadvantage which makes me unable to implement the application domains for hosting the plugins. It seems there is no way to pass an object by reference to another application domain which is needed to pass an reference to the connection object.
I was hoping someone could give me a workaround so I can pass an reference to that object.
Note: Creating a proxy is out of the question, the connection layer already acts as a proxy since the classes are auto generated.
Note2: System.AddIn can not be used as it is not available on the compact framework.
Have you tried deriving from MarshalByRefObject? It's a pain in that it screws up your inheritance hierarchy, but I think it's what you want.
From the docs:
MarshalByRefObject is the base class
for objects that communicate across
application domain boundaries by
exchanging messages using a proxy.
Objects that do not inherit from
MarshalByRefObject are implicitly
marshal by value. When a remote
application references a marshal by
value object, a copy of the object is
passed across application domain
boundaries.
MarshalByRefObject objects are
accessed directly within the
boundaries of the local application
domain. The first time an application
in a remote application domain
accesses a MarshalByRefObject, a proxy
is passed to the remote application.
Subsequent calls on the proxy are
marshaled back to the object residing
in the local application domain.
Types must inherit from
MarshalByRefObject when the type is
used across application domain
boundaries, and the state of the
object must not be copied because the
members of the object are not usable
outside the application domain where
they were created.
In my experience, it can be pretty limiting - you really need to do as little as possible across the AppDomain boundary, preferrably restricting yourself to operations which only require primitive types, strings, and arrays of both. This may well be due to my own inexperience in working with multiple AppDomains, but it's just a warning that it's a bit of a minefield.
To talk to the same instance between AppDomains, it must inherit from MarshalByRefObject. Done this way, every method call to the object (including properties etc) is actually a remoting call to the other app-domain. Does that help?
Be aware that clean-up of MarshalByRefObject proxies are cleaned up based on a lease. In short if you don't use the object for a specific time it will be reclaimed. You can control this by overriding InitializeLifetimeService to return a lease object which matches you needs. If you return null you effectively disable the leasing and then the object is only reclaimed when the AppDomain is unloaded.