почему AssemblyResolve не работает? - PullRequest
2 голосов
/ 16 марта 2012

Мне действительно интересно, почему не работает AssemblyResolver?Также я не могу использовать

foreach (байт [] двоичный в deCompressBinaries)
ApplicationHost.Load (двоичный);

как запустить AssemblyResolve?пожалуйста посмотрите мой справочный вопрос: /5016178/kak-ispolzovat-appdomain-createdomain-s-assemblyresolve

    protected void LoadApplication()
    {

        AppDomainSetup domainSetup = new AppDomainSetup();
        domainSetup.ApplicationBase = AppDomain.CurrentDomain.BaseDirectory;
        domainSetup.DisallowBindingRedirects = false;
        domainSetup.DisallowCodeDownload = true;
        domainSetup.LoaderOptimization = LoaderOptimization.SingleDomain;
        //domainSetup.ConfigurationFile = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile;
        ApplicationHost = AppDomain.CreateDomain("Test.Service", null, domainSetup);
        object obj = ApplicationHost.CreateInstanceAndUnwrap("Test.Process", "Test.ApplicationLoader");

        Assembly objExecutingAssemblies = Assembly.GetExecutingAssembly();
        AssemblyName[] arrReferencedAssmbNames = objExecutingAssemblies.GetReferencedAssemblies();

        foreach (AssemblyName assName in arrReferencedAssmbNames)
        {
            ApplicationHost.Load(assName);
        }


        ApplicationHost.AssemblyResolve += new ResolveEventHandler(OnAssemblyResolve);

        List<byte[]> deCompressBinaries = new List<byte[]>();
        foreach (var item in AppPackage.Item.AssemblyPackage)
            deCompressBinaries.Add(item.Buffer);
        var decompressvalues =  DeCompress(deCompressBinaries);
        deCompressBinaries.Clear();
        deCompressBinaries = decompressvalues.ToList();

        foreach (byte[] binary in deCompressBinaries)
            ApplicationHost.Load(binary);

        Assembly[] assAfter = AppDomain.CurrentDomain.GetAssemblies();
    }

    Assembly OnAssemblyResolve(object sender, ResolveEventArgs args)
    {
        return Assembly.Load(args.Name);
    }

Ответы [ 2 ]

3 голосов
/ 16 марта 2012

AssemblyResolve никогда не сработает, потому что вы загружаете все сборки с помощью метода LoadApplication - AssemblyResolve будет вызываться только в том случае, если требуемая ссылка на сборку не может быть разрешена.

Я бы предложил запустить fuslogvw.exe , чтобы вы могли визуализировать происходящее.

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

List<byte[]> deCompressBinaries = new List<byte[]>();
foreach (var item in AppPackage.Item.AssemblyPackage)
deCompressBinaries.Add(item.Buffer);
var decompressvalues =  DeCompress(deCompressBinaries);
deCompressBinaries.Clear();
deCompressBinaries = decompressvalues.ToList();

foreach (byte[] binary in deCompressBinaries)
    ApplicationHost.Load(binary);

Assembly[] assAfter = AppDomain.CurrentDomain.GetAssemblies();

нужно будет включить в AssemblyResolve. Блок в настоящее время загружает ВСЕ в AppDomain, поэтому вам придется переделать этот кусок логики.

Конечно, другое, что вы можете сделать, это не изобретать велосипед, а использовать ILMerge .

2 голосов
/ 16 марта 2012

AssemblyResolve При заполнении только CLR не удалось загрузить сборку по одной из причин.Это событие не сработает только потому, что вы загружаете свои сборки из байтового массива.

Вот несколько примеров.

  • Этот код будет fire * 1011Событие * AssemblyResolve , поскольку «System.Drawing» в качестве имени сборки недостаточно.

    object obj2 = ApplicationHost.CreateInstanceAndUnwrap("System.Drawing", "System.Drawing.Rectangle");
    
  • Этот код не будет вызывать Событие AssemblyResolve , поскольку «System.Drawing, версия = 4.0.0.0, Culture = нейтральный, PublicKeyToken = b03f5f7f11d50a3a» является полностью определенным именем сборки.

    object obj2 = ApplicationHost.CreateInstanceAndUnwrap("System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "System.Drawing.Rectangle");
    
...