Общий контейнер для предоставления экземпляров POCO другим доменам приложений - как это работает? - PullRequest
1 голос
/ 30 апреля 2009

Я заинтригован этим ответом из другой 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> (который сам по себе является маршалируемым) должен позволить передать его обратно в основной AppDomain. Я понимаю это, потому что это действительно прокси для Container<MyInfo> экземпляра.

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

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

1 Ответ

1 голос
/ 30 апреля 2009

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

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

...