contêiner genérico para expor casos POCO para outros AppDomains - como funciona?
-
03-07-2019 - |
Pergunta
Estou intrigado com esta resposta de outro segmento SO, e Eu estava esperando que alguém pode me ajudar a brilhar alguma luz sobre o conceito.
dizer que tenho um AppDomain primário e um monte de AppDomains criança, que são criados e inicializados pela AppDomain primário. No código pseudo:
Primária AppDomain:
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.
}
}
Criança AppDomain:
class Child : MarshalByRefObject
{
public void Init(Parent parent)
{
parent.Register(new Container<MyInfo>(new MyInfo()));
}
}
class MyInfo : BasePoco // <- not a MarshalByRefObject!
{
public MyInfo() { ... }
}
Durante Init (), uma criança AppDomain instancia um objeto POCO, que é não-marshalable por definição. Vamos supor também que não podemos modificá-lo a esse respeito.
A resposta vinculada sugere que envolvê-lo em uma Container<T>
(que por si só é marshalable) deve permitir que ele seja passado para trás AppDomain primário. Eu entendo isso porque é o proxy para instância Container<MyInfo>
que realmente é passado através de.
O que eu não entendo é como a principal AppDomain pode possivelmente acessar a instância POCO no recipiente através do procuração do recipiente . Eu vejo o operador de conversão implícita sobrecarregado em Container<T>
e eu entendo ele retorna a instância POCO contido. Mas essa instância não está sendo proxy em si - ainda é na criança AppDomain! Assim, não deve esta ruptura?
O que realmente está acontecendo aqui?
Solução
Assim que o recipiente retorna a instância que vive em outro AppDomain (se isso acontece via Valor propriedade ou operador de conversão implícita), o objeto será comandada. Se é um MarshalByRefObject, um novo proxy será gerado para que você possa acessá-lo. Caso contrário, o objeto será copiado (comandada por valor, serializado) no domínio de aplicativo atual.
A única coisa que a classe Container mostrado nessa questão pode ajudar com é se você quiser manter um proxy para outro objeto que não deve ser comandada. Mas neste caso, você não deve acessar a propriedade Value ou utilize o operador de conversão implícita do AppDomain onde vive de proxy, pois isso faria com que o objeto no recipiente para ser empacotado. Ainda assim, é possível utilizar o recipiente como argumento para um método de um objecto vivo no mesmo domínio de aplicação, como o objecto de recipiente, pois, basicamente permitindo-lhe manter uma referência a um objecto que não seja marshallable (não seriável e não MarshalByRef, ou de um tipo em uma montagem que não pode ser carregado para o domínio de aplicação com o proxy etc.) e para passá-lo ao redor como um "punho".