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...
Related
I have a large app which uses COM via .net remoting to call from the web tier to the middle tier.
It's quite slow to startup and to run when in this mode. Both sides of the COM boundary are our code.
I'd like to be able to (optionally) run it in a single process.
Quite a bit of the behaviour relies on calls to ServicedComponents having all their arguments serialized, and that changes made to the objects inside the components don't leak out unless the argument is a 'ref' argument.
My current plan to force this two-process app into a single process without needing to change too much code is by using a fake middle tier boundary with custom .net remoting.
If I change all the:
class BigComponent : ServicedComponent {
...
}
into
[FakeComponent]
class BigComponent : ContextBoundObject {
...
}
Then I can write a custom ContextAttribute to fake the process boundary and make the arguments serialize themselves:
i.e.
[AttributeUsage(AttributeTargets.Class)]
public class FakeComponentAttribute :
ContextAttribute,
IContributeServerContextSink
{
... lots of stuff here
}
As per http://msdn.microsoft.com/en-us/magazine/cc164165.aspx
Now this works fine, so far, and I can intercept all calls to methods on these classes.
However, I can only view the IMethodCallMessage.Args in the IMessageSink.ProcessMessage call -- I don't seem to be able to replace them with objects of my choice.
Any time I change entries in the IMethodCallMessage.Args array, my changes are ignored. From what I can tell in Reflector, this interface is a wrapper around a native object in the runtime itself, and I can't write to this object, just read it.
How can I modify the arguments to method calls in .net remoting?
Do I need to implement my own Channel? Is there a "local" channel tutorial out there I can crib from?
My aim is to have these Components act like remote objects (in that all their args get serialized on the way in to the method, and that their return value is serialized on the way out), but have the remote endpoint be inside the same process.
I have not found a way to edit the argument array as it passes through the IMessageSink.
In the end, I had to make the argument object classes aware of this issue, and implement a new interface IFakeRemotingAware. This allowed the complex object arguments which exhibit the pass-by-val behaviour due to serialization/deserialization when using remoting to simulate that behaviour when using fake remoting.
The interface has two methods: EnteringFakeRemote which causes the object to cache a local copy of its state, and LeavingFakeRemote which causes the object to restore its state from the cache.
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.
How to dispose objects in a Singleton WCF service? I am using Entity Framework (3.5) and returning a bunch of custom POCO objects to the client. The service needs to be alive as it provides cross-client communication and hence Duplex binding is used. I would like dispose all the POCO objects created once they are serialized to the client.
As the session and hence the service is still alive, it looks like Framework is not doing any Garbage collection on these objects and over time the service is crashing with "Insufficient Memory" like error (after about 2GB).
I don't think dispose can be called before return statement, as the objects are not yet serialized by then.
Please suggest a solution.
Thanks in advance.
First, do not use singleton service, why, well your question is the answer.
As I see it your service should be a per call instance managed and the callback channels should be managed on another class or as static member in the service class.
Second, try to see if you keep reference to the poco's you return to client, Cause GC cleans unreferenced stuff. So if you find the reference just assign those member with null and GC will do the rest(you have nothing to worry about method variables).
I think you're on the wrong track here; if your objects are POCO, do they even implement IDisposable (not sure why you would for a POCO class). My guess is you've got something else that is chewing up your memory. Possibly your singleton service is just living too long and collecting too much crap; you might want to look at a different service model. Maybe an instance per session or something like that.
One thing you could do, however, is rather than serializing your POCO objects directly create very simple 'messaging' classes that have only the properties you want to serialize and send those instead. You could copy the properties to your message objects and then dispose your database objects immediately.
I just wanna learn why I can't static web methods in web services ? Why is it restricted ?
Can some body give me concise explanation of this.
The answer is: because you can't.
It's not designed that way. The design is that an instance of the web service class will be created, and then an instance method will be called.
I can only guess why Microsoft designed it that way. To know for sure, you'd have to ask them. Consider:
There's no particular benefit to permitting static methods. Anything you can do with a static method, you can also do with an instance method.
A [WebService] class is not meant to be some arbitrary class that happens to be used as a web service. It's meant to be a class that you created for the purpose of exposing web service operations. As such, there is no need to support classes that already exist and already have static methods.
The SOAP Header implementation permits your class to contain an instance field of a type deriving from the SoapHeader class. This field will be filled with an incoming SOAP header and/or will contain the SOAP Header to be returned. You could not do this with a static field, as it would be overwritten with each request.
As I said, these are all guesses. The correct answer to the question is, "you can't because that's how Microsoft designed it. If you want to know why they designed it that way, you need to ask them".
FWIW, I just checked, and it does not appear that WCF permits static methods to be operations either.
When a client creates an object for your web service, what they are really creating is a proxy object to that web service. This proxy object handles things like opening and closing your connections for you as well as all the overhead of actually working with the web service. A static method call would be difficult to manage. The "static proxy" for lack of a better word would have to do all of things that the instance of the proxy object is doing each and every time a client called one of the static methods, thus adding massive overhead.
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.