MarshalByRefObject передаётся по ссылке или делает копию?
1,00
р.
р.
Есть 2 AppDomain с LoaderOptimization = LoaderOptimization.MultiDomainHost. Есть общая сборка, скажем Common.dll, которая загружена в AppDomain1 и в AppDomain2. В сборке Common.dll есть класс: class MethodArgs:MarshalByRefObject { public string MethodName { get private set } ... } При передаче экземпляра этого класса из AppDomain1 в AppDomain2 передача идёт по ссылке или всё же копируется, а потом делается ссылка?
Ответ Несмотря на название класса MarshalByRefObject, передача происходит не совсем по ссылке. Упрощенная схема выглядит примерно так: На вызывающей стороне создается два прокси - System.Runtime.Remoting.Proxies.__TransparentProxy, который по всем признакам является объектом оригинального типа - MethodArgs, и RealProxy, который умеет перебрасывать вызов в другой домен. Рантайм перехватывает все обращения к методам и свойствам прокси, и проверяет, находится ли их реальный объект для этого __TransparentProxy в другом домене. Если объект в том же домене - то происходит простой вызов метода. Иначе - рантайм собирает все параметры, оборачивает их в IMessage, и отдает его в метод RealProxy.Invoke(...). RealProxy (точнее, его реализация для кросс-доменных вызовов) перебрасывает вызов в другой домен, десериализует параметры и вызывает метод у реального объекта. __TransparentProxy - системный класс, и его поведение нельзя поменять. Поведение RealProxy, напротив, можно полностью кастомизировать, что позволяет использовать его, например, трассировки/подмены результатов вызовов - создания моков. Или для балансировки нагрузки - перенаправления вызовов от одного __TransparentProxy к нескольким реальным объектам. Аттрибут LoaderOptimization.MultiDomainHost не оказывает никакого влияния на поведение MarshalByRefObject. Более подробно о механизме proxy в ремоутинге: Microsoft .NET Remoting: A Technical Overview Transparent Proxy