Проблемы с событием AssemblyResolve на созданном домене приложений - PullRequest
2 голосов
/ 30 июня 2010

Я пытаюсь настроить процесс разрешения сборки, поместив AppDomain и его AssemblyResolve в класс. Упрощенная версия моего ClassLoader приведена ниже. Проблема, с которой я сталкиваюсь, заключается в том, что при запуске события AssemblyResolve мне кажется, что я получаю новый экземпляр ClassLoader, а не тот, который я создал ранее.

[Serializable]
public class ClassLoader // : IDisposable
{
    public AppDomain Domain { get; private set; }
    public string FooProperty { get; set; }

    public ClassLoader(string domain) {
        Domain = AppDomain.CreateDomain(domain);
        Domain.AssemblyResolve += Domain_AssemblyResolve;
    }

    private Assembly Domain_AssemblyResolve(object sender, ResolveEventArgs args)
    {
        Console.WriteLine(
            "ClassLoader HashCode: {0} FooProperty: {1}\n\n", 
            GetHashCode(), 
            FooProperty);
        // ...
        return null;
    }
    // ...
}

При выполнении этого кода FooProperty не инициализируется в обработчике событий Domain_AssemblyResolve, а экземпляр ClassLoader имеет хеш-код, отличный от «c».

 var c = new ClassLoader("demo");
 c.FooProperty = "Foo";
 Console.WriteLine(
     "c Hash Code: {0} FooProperty: {1}", 
     c.GetHashCode(), 
     c.FooProperty);
 c.Domain.CreateInstanceAndUnwrap("Not important", "Not important");

У тебя что происходит? или какой-то обходной путь?

Спасибо!

Ответы [ 2 ]

2 голосов
/ 30 июня 2010

Экземпляр ClassLoader c создается в домене приложения A и, поскольку он не наследуется от MarshalByRefObject, он будет сериализован в домен приложения, который вы создаете в момент добавления обработчика события в AssemblyResolve. Это происходит потому, что метод является методом экземпляра, а делегату потребуется ссылка на целевой объект, где будет вызываться метод.

Если вы просто хотите, чтобы FooProperty имел определенное значение при срабатывании обработчика событий, вы можете добавить обработчик событий только после инициализации свойства, в результате чего значение будет сериализовано и доступно во вновь созданном домене приложения.

public string FooProperty { get; private set; }

public ClassLoader(string domain, string fooProperty)
{
    FooProperty = fooProperty; // Set it before adding event handler
    Domain = AppDomain.CreateDomain(domain);
    Domain.AssemblyResolve += Domain_AssemblyResolve;
}

Если у вас есть требование, чтобы экземпляр c был доступен в обоих доменах приложений, вам следует взглянуть на:

Создание объектов с возможностью удаления

События и делегаты с .NET Framework Remoting

0 голосов
/ 30 июня 2010

Ну,

При выполнении этого кода FooProperty не инициализируется в событии Domain_AssemblyResolve

Кажется, что нет никакого кода, который инициализирует Fooвнутри обработчика.

экземпляр ClassLoader имеет хеш-код, отличный от "c".

Экземпляры классов, которые наследуются от Object (например, ClassLoader) и don'reimplement GetHashCode(), как и в вашем случае, будет иметь разные хеш-коды (в зависимости от адреса объекта).Переопределите GetHashCode(), если вы хотите, чтобы согласованные коды основывались на внутреннем состоянии.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...