У меня есть сценарий, в котором я хотел бы достичь простой связи между родителем AppDomain
и его детьми. То, что я пытаюсь сделать, похоже, что это сработает, но я столкнулся с проблемой, приведенный ниже фрагмент является примером.Как передать строго типизированный объект MarshalByRefObject через границу AppDomain?
Результаты программы в сообщении Нет конструктор нашел для C ::. Т е р (System.MarshalByRefObject) так это выглядит, как среда выполнения отклонило конструктор, принимающий параметр типа, который я передаю в к CreateInstanceFromAndUnwrap
call. Я могу понять, почему работает экземпляр B
, и я ожидал, что C
будет вести себя одинаково, так почему же это не так?
Спасибо!
EDIT: Я сделал небольшое обновление примера кода ниже, после того как Ганс указал на ошибку пешехода в моем первом примере. Поэтому, пока у нас еще есть вымышленное свойство ApplicationBase
на наших дочерних доменах приложений, мы можем видеть, что загружается правильная сборка, и мы можем вызвать конструктор, который мы пытаемся вызвать.
Замечание Ганса делает, чтобы сделать код, но я не думаю, что я могу установить ApplicationBase в реальной вещи, чтобы быть базой родительского домена.
Выход на второй итерации цикла теперь следующим образом:
C
Первоначально Загруженный: mscorlib
После Unwrap: mscorlib
После Unwrap: Foo
Пустота .ctor (A)
Конструктор по типу 'C' не найден.
using System;
using System.Linq;
using System.Reflection;
class A : MarshalByRefObject { }
class B : MarshalByRefObject
{
public B(MarshalByRefObject obj) { }
}
class C : MarshalByRefObject
{
public C(A obj) { }
}
static class Program
{
static void Main(string [] args)
{
foreach (var type in new [] { typeof(B), typeof(C) })
{
try
{
Console.WriteLine(type.FullName);
var setup = CreateSetup();
var domain = AppDomain.CreateDomain("foo", AppDomain.CurrentDomain.Evidence, setup);
foreach (var ass in domain.GetAssemblies())
{
Console.WriteLine("Initially Loaded: {0}", ass.GetName().Name);
}
domain.CreateInstanceFromAndUnwrap(typeof(A).Assembly.Location, typeof(A).FullName);
foreach (var ass in domain.GetAssemblies())
{
Console.WriteLine("After Unwrap: {0}", ass.GetName().Name);
}
var constructors = domain.GetAssemblies()
.ToList()
.SelectMany(ass => ass.DefinedTypes)
.First(t => t.Name == "C")
.GetConstructors();
foreach (var constructor in constructors)
{
Console.WriteLine(constructor);
}
CreateWrapped(domain, type);
AppDomain.Unload(domain);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}
static AppDomainSetup CreateSetup()
{
return new AppDomainSetup
{
ApplicationBase = "foo",
ApplicationName = "bar",
DisallowBindingRedirects = false,
ConfigurationFile = "baz",
LoaderOptimization = LoaderOptimization.MultiDomainHost
};
}
static object CreateWrapped(AppDomain domain, Type type)
{
return domain.CreateInstanceFromAndUnwrap(
assemblyFile: type.Assembly.Location,
typeName: type.FullName,
ignoreCase: false,
bindingAttr: BindingFlags.Default,
binder: null,
args: new object[] { new A() },
culture: null,
activationAttributes: null
);
}
}
AppDomainSetup.ApplicationBase - проблема. Разрешение типа A - проблема с курицей и яйцом, она не может найти сборку, содержащую A. –
О, боже, как я пропустил это, когда писал это. Моя настоящая проблема не должна быть зафиксирована в этом Минимальном нерабочем примере. – arfbtwn
@ HansPassant, я обновил образец, не могли бы вы взглянуть еще раз? – arfbtwn