Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ability to add different NuGet package versions in plugins #2523

Closed
marius-stanescu opened this issue Aug 29, 2017 · 5 comments
Closed

Ability to add different NuGet package versions in plugins #2523

marius-stanescu opened this issue Aug 29, 2017 · 5 comments

Comments

@marius-stanescu
Copy link

marius-stanescu commented Aug 29, 2017

I am developing a plugin which needs the latest version of AutoMapper (6.1.1). But Nop.Admin aswell as another third party plugin use AutoMapper 4.1.1 (I currently have nopCommerce 3.70, but the problem is the same for all versions of nopCommerce).

The error is the following:

Could not load file or assembly 'AutoMapper, Version=6.1.1.0, Culture=neutral, PublicKeyToken=be96cd2c38ef1005' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.IO.FileLoadException: Could not load file or assembly 'AutoMapper, Version=6.1.1.0, Culture=neutral, PublicKeyToken=be96cd2c38ef1005' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)

Source Error:

Line 364:
Line 365:            //we can now register the plugin definition
Line 366:            var shadowCopiedAssembly = Assembly.Load(AssemblyName.GetAssemblyName(shadowCopiedPlug.FullName));
Line 367:
Line 368:            //add the reference to the build manager

Source File: C:\Projects\Apps\KitchenShop\KitchenShop.Store\src\Libraries\Nop.Core\Plugins\PluginManager.cs Line: 366

Assembly binding redirect won't work because the plugin versions are very different and the methods have changed.

@AndreiMaz
Copy link
Member

@shurub3l in this case you have to use the version the admin area uses - 4.1.1

@marius-stanescu
Copy link
Author

But I need a newer version of AutoMapper, that's the problem ... I could update Nop.Admin to use the newer version aswell, but I don't have access to the third party plugin that also uses AutoMapper 4.1.1.

@AndreiMaz
Copy link
Member

@shurub3l thanks. we'll think about it

@marius-stanescu
Copy link
Author

marius-stanescu commented Aug 30, 2017

I found a workaround for my problem. I changed the code to compare full assembly name when checking if an assembly is already loaded and, I added in web.config a codeBase element for every AutoMapper version. This way the different version nuget package assembly is not skipped when loading assemblies and every assembly is loaded from the correct file path.

So the method IsAlreadyLoaded from PluginManager becomes:

private static bool IsAlreadyLoaded(FileInfo fileInfo)
{
    //compare full assembly name
    try
    {
        var fileAssemblyName = AssemblyName.GetAssemblyName(fileInfo.FullName);
        foreach (var a in AppDomain.CurrentDomain.GetAssemblies())
        {
            if (a.FullName.Equals(fileAssemblyName.FullName, StringComparison.InvariantCultureIgnoreCase))
                return true;
        }
    }
    catch (Exception exc)
    {
        Debug.WriteLine("Cannot validate whether an assembly is already loaded. " + exc);
    }
    return false;

    //do not compare the full assembly name, just filename
    //try
    //{
    //    string fileNameWithoutExt = Path.GetFileNameWithoutExtension(fileInfo.FullName);
    //    if (fileNameWithoutExt == null)
    //        throw new Exception(string.Format("Cannot get file extnension for {0}", fileInfo.Name));
    //    foreach (var a in AppDomain.CurrentDomain.GetAssemblies())
    //    {
    //        string assemblyName = a.FullName.Split(new[] { ',' }).FirstOrDefault();
    //        if (fileNameWithoutExt.Equals(assemblyName, StringComparison.InvariantCultureIgnoreCase))
    //            return true;
    //    }
    //}
    //catch (Exception exc)
    //{
    //    Debug.WriteLine("Cannot validate whether an assembly is already loaded. " + exc);
    //}
    //return false;
}

And added this in web.config file from Nop.Web:

<dependentAssembly>
  <assemblyIdentity name="AutoMapper" publicKeyToken="be96cd2c38ef1005" culture="neutral" />
  <codeBase version="6.1.1.0" href="Plugins\Integration.ServiceBus\AutoMapper.dll" />
  <codeBase version="4.1.1.0" href="bin\AutoMapper.dll" />
</dependentAssembly>

@AndreiMaz
Copy link
Member

Until we load plugins in separate domains it's better to avoid usage of diffrerent versions. So we don'y plan to support it in the near time

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants