Общий контейнер для предоставления экземпляров POCO другим доменам приложений — как это работает?

StackOverflow https://stackoverflow.com/questions/806744

Вопрос

я заинтригован этот ответ из другой темы SO, и я надеялся, что кто-нибудь поможет мне пролить свет на эту концепцию.

Допустим, у меня есть основной домен приложения и несколько дочерних доменов приложений, которые создаются и инициализируются основным доменом приложения.В псевдокоде:

Основной домен приложения:

class Parent
{
    public void InitChildren(IList<ChildInfo> children)
    {
        foreach (var childInfo in children)
        {
            var ad = CreateNewChildAppDomain();
            var child = (Child)ad.CreateInstanceAndUnwrap(typeof(Child));
            child.Init(this);
        }
    }

    public void Register(BasePoco info)
    {
        // Do something with info.
    }
}

Дочерний домен приложения:

class Child : MarshalByRefObject
{
    public void Init(Parent parent)
    {
        parent.Register(new Container<MyInfo>(new MyInfo()));
    }
}

class MyInfo : BasePoco // <- not a MarshalByRefObject!
{
    public MyInfo() { ... }
}

Во время Init() дочерний AppDomain создает экземпляр объекта POCO, который по определению не является маршалируемым.Предположим также, что мы не можем изменить его в этом отношении.

Связанный ответ предполагает, что обернуть его в Container<T> (что само по себе является marshalable) должен разрешить его передачу обратно в основной домен приложения.Я понимаю это, потому что это прокси для Container<MyInfo> экземпляр, который действительно передается.

Чего я не понимаю, так это того, как основной домен приложения может получить доступ к экземпляру POCO в контейнере через прокси контейнера.Я вижу перегруженный оператор неявного приведения в Container<T> и я понимаю, что он возвращает содержащийся экземпляр POCO.Но сам этот экземпляр не проксируется — он все еще находится в дочернем домене приложений!Так разве это не должно сломаться?

Что здесь происходит на самом деле?

Это было полезно?

Решение

Как только контейнер вернет экземпляр, находящийся в другом AppDomain (происходит ли это через свойство Value или оператор неявного преобразования), объект будет маршалирован.Если это MarshalByRefObject, будет создан новый прокси-сервер, чтобы вы могли получить к нему доступ.В противном случае объект будет скопирован (упорядочен по значению, сериализован) в текущий домен приложения.

Единственное, в чем может помочь класс Container, показанный в этом вопросе, - это если вы хотите сохранить прокси для другого объекта, который не следует маршалировать.Но в этом случае вы не должны обращаться к свойству Value или использовать оператор неявного преобразования из AppDomain, где находится прокси, поскольку это приведет к маршалированию объекта в контейнере.Тем не менее, вы можете использовать контейнер в качестве аргумента в методе объекта, находящегося в том же AppDomain, что и объект Container, что в основном позволяет вам сохранять ссылку на немаршализуемый объект (не сериализуемый и не MarshalByRef или типа в сборке, которую нельзя загрузить в AppDomain с помощью прокси и т. д.) и передать ее как «дескриптор».

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top