Использование двух DLL с одинаковым именем и одним и тем же пространством имен

У меня есть проект, который должен ссылаться на две библиотеки DLL с тем же именем. DLL не имеют сильного имени, имеют то же точное имя.

Мне нужно получить доступ к некоторым типам в каждой DLL, но эти типы имеют одинаковое полное имя. Так что скажем, DLL1 - companyDLL.dll → someProduct.Type1 DLL 2 - companyDLL.dll → someProduct.Type1

Как я могу получить доступ к "Type1" в рамках одного и того же проекта?

Я уже пытался использовать "extern alias", но мне требуется изменить имя одной из DLL.

Пожалуйста, дайте мне знать, если для моего вопроса требуется дополнительное разъяснение.

Ответ 1

Если ваши две библиотеки DLL имеют одинаковое имя, вам придется переименовать их. Например, Assembly1.dll и Assembly2.dll.

Добавьте эти DLL в качестве ссылки в свой проект, как обычно, и в свойствах для каждой ссылки укажите псевдоним.

в вашем коде при использовании DLL используйте extern alias, чтобы указать, какую dll вы хотите ссылаться.

extern alias Assembly1Reference;
using Assembly1Reference::AssemblyNamespace.MyClass;

Если вы оставите его таким образом, скорее всего, получите сообщение FileNotFoundException, в котором говорится, что он не может загружать файл или сборку. Чтобы исправить это, вам нужно добавить ResolveEventHandler, который будет загружать нужную сборку, которую вы пытаетесь использовать. Для этого вам нужно точно указать, где вы храните файлы DLL. В приведенном ниже примере я вручную скопировал файлы Dll в папку для отладки проектов. Где он говорит "имя сборки1", вы можете найти это имя после ссылки на DLL, построить проект и открыть файл csproj с помощью блокнота. То, что нужно искать, будет ниже моего кода примера.

extern alias Assembly1Reference;
extern alias Assembly2Reference;

static void Load()
{
    AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
    Do();
}

static void Do()
{
    new Assembly1Reference.Assembly.Class();
    new Assembly2Reference.Assembly.Class();
}

static System.Reflection.Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
    string currentPath = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
    if(args.Name == "Name of assembly1")//Found in csproj file after referenced and built
    {
        return System.Reflection.Assembly.LoadFile(System.IO.Path.Combine(currentPath, "Assembly1.dll"));
    }
    if(args.Name == "Name of assembly2")//Found in csproj file after referenced and built
    {
        return System.Reflection.Assembly.LoadFile(System.IO.Path.Combine(currentPath, "Assembly2.dll"));
    }
    return null;
}

Как и было обещано, вот что выглядит ссылка в файле csproj. Имя - это все внутри атрибута include.

<Reference Include="MyAssembly_3.6.2.0, Version=3.6.2.0, Culture=neutral, PublicKeyToken=12341234asdafs43, processorArchitecture=MSIL">
      <SpecificVersion>False</SpecificVersion>
      <HintPath>Resources\Assembly1.dll</HintPath>
      <Aliases>Assembly1Reference</Aliases>
</Reference>

Я знаю, что это поздно, но, надеюсь, это поможет любому, кто придет на эту страницу с этого момента.

Ответ 2

Используя extern alias, чтобы собрать сборки в разных пространствах имен. Если вы можете различать пространство имен, вы можете использовать using altType1 = someProduct.Type1 для создания локального псевдонима для типа.

Сначала квалифицируйте сборки из командной строки:

/r:ProductA=companyDLLA.dll
/r:ProductB=companyDLLB.dll

Затем ссылайтесь на них с помощью extern alias:

extern alias productA;
extern alias productB;

Наконец, вы можете использовать псевдонимы локальных типов:

using productTypeA = productA.Type1;
using productTypeB = productB.Type1;

Ответ 3

Я могу представить два способа справиться с этим.

  • загружать каждую DLL в отдельный AppDomain. Вам придется совершать вызовы через границу AppDomain, чтобы щекотать различные свойства и методы.

  • прежде чем загружать сборки, разбирать, а затем повторно собирать каждую сборку и помещать их в уникальные (возможно, динамически созданные) пространства имен. Есть инструменты, которые могут помочь с этим (1) (2). Вы могли бы автоматизировать его.

Но мое базовое чувство, вы действительно не должны этого делать. Легче решить эту проблему вверх по течению, чем решить ее после того, как вы уже собрали сборки.