100

I have created two .NET Interop assemblies from two different third-party COM DLLs. Both of the COM DLLs contained a type named COMMONTYPE. Therefore, COMMONTYPE is now exposed through the two Interop assemblies as well.

I have a third project that needs to use these two Interop assemblies, and I get the infamous compile time error:

The type <ABC> exists in both <ASSEMBLY1.dll> and <ASSEMBLY2.dll>

Since the COM DLLs are provided by a third-party vendor, I have no access to the source code, and I'm writing a C# Console application, which means I have no web.config file where I could add the debug=false workaround. What can I do?

FishBasketGordo
  • 22,904
  • 4
  • 58
  • 91
Kou S Hal
  • 1,001
  • 2
  • 7
  • 4
  • I got here because Visual Studio was complaining about the type JsonConvert exists in both Newtonsoft.Json.Torq and Newtonsoft.Json – Matthew Dec 20 '17 at 00:38

6 Answers6

224

I know this is old, but there's an easier way than the listed. This works when you reference two assemblies that share types with the exact same name and namespace.

If you right-click on the Reference to your DLL and select Properties, you will see that here's a property called "Aliases"

enter image description here

The default value is "global". For one of the conflicting assemblies change this to any other value. In the example below, I've changed it from "global" to "destination".

Next, in your code file, you will have to use the extern keyword to use this alias as the root-level namespace for these types. In this example, you would place the following at the top of your .cs file:

extern alias destination

Now, within this file, you can reference both types.

extern alias destination;
namespace Test
{
    public static class TestClass
    {
        public static void Success()
        {
            var foo = destination::Some.Duplicate.Namespace.SomeDuplicateType();
            var bar = Some.Duplicate.Namespace.SomeDuplicateType();
        }
    }
}
Aage
  • 5,932
  • 2
  • 32
  • 57
Tom
  • 2,830
  • 1
  • 18
  • 22
  • 5
    For me also definitely best answer. Other solutions wouldn't even work, cause I have two exactly same dlls, one is just merged within another with ILMerge. Problem solved – Johnny Sep 05 '15 at 19:04
  • 1
    I'd like to re-ask a question from @bunkerdive here (the most popular answer): How do you get this working with NuGet packages? If you try and change the Alias VS gives you an error: Cannot modify an evaluated object originating in an imported file – Geordie Sep 25 '17 at 21:23
  • 2
    I went into references, selected the package that was installed by Nuget and then set the alias to destination. Worked like a charm... – Zonus Mar 20 '18 at 16:05
  • Has the Aliases property of a Reference gone away? I'm using VS 2017 Community and I can't find this option! – Pedro Gaspar Dec 05 '18 at 17:18
  • 1
    @PedroGaspar might be because you are using Visual Studio "Community". I am on VS2017 Enterprise and I just implemented this 5 seconds ago. Some lower level versions of VS don't have good support for unit testing. – AlbatrossCafe Feb 15 '19 at 22:38
  • What to do if both the assemblies are not directly accessible, but are referenced inside another assemblies? I cannot provide aliases then. – Alexander May 24 '22 at 17:04
  • Did this fix and it worked for one day and now its completely jammed up the build process. This is a C# WPF application, and when I run build, let it hang, and cancel after some time, diagnostic details always shows that its hung up on `GenerateTemporaryTargetAssembly` – Narish May 02 '23 at 15:55
20

Old question but found an easier option... Select the reference you want to use... Under properties, change the Aliases to 'xyz' Now in code line, at the top add:

extern alias xyz;

then add using:

using xyz.VENDOR2.Type;

or another way of to use using:

using OtherNameSpace = xyz.VENDOR2.Type;

now you should be able to use the reference explicitly as below:

var abc = new xyz.VENDOR2.Type.abc();

or

var abc = new OtherNameSpace.abc();
Zunair
  • 1,085
  • 1
  • 13
  • 21
  • 7
    How though, can this be accomplished when it's a NUGET package being referenced, instead of a regular dll? – bunkerdive Sep 28 '16 at 23:42
  • 1
    @bunkerdive It mostly likely will work the same way with or without a NuGet package. When you install a NuGet package references to the assemblies in the package should be added to your Visual Studio project automatically. Look under the *References* node under your project in the *Solution Explorer" view pane. – Kenny Evitt May 01 '17 at 20:17
  • 1
    @bunkerdive With a NuGet package and VS2017 you don't get an alias option under the properties. So you must follow the answer to add a manual alias in .csproj file. Look for answer with `` examples. – Wasted_Coder Feb 15 '22 at 18:33
14

Unless the namespaces of the vendors are identical (unlikely), the type definitions will actually be separate at that point. What you'll need to do (and this is a complete PITA sometimes) is create a namespace alias in your using statement rather than simply applying the statement carte blanche. This will allow you to re-identify the namespaces:

using Vendor1 = Vendor.Namespace;
using Vendor2 = OtherVendor.Namespace;

...

Vendor1.COMMONTYPE blah = new Vendor1.COMMONTYPE();
Vendor2.COMMONTYPE blah2 = new Vendor2.COMMONTYPE();

This will mean using the specific alias for all types located in each namespace for these vendors.

Joel Etherton
  • 37,325
  • 10
  • 89
  • 104
  • This would surely help me to resolve the compile time errors. But isn't there anything I can do to make .NET ignore particular types while creating an assembly so that I'll have the common type in only 1 of the assemblies..?? – Kou S Hal Feb 09 '12 at 08:31
  • 1
    @KouSHal: The only way to do that would be to build a wrapper class that referenced one of the vendor libraries and exposed all of the classes, extensions methods, etc as a proxy. If it's small library with only a few classes this wouldn't be too hard, but if it's like most vendor libraries this would be a nightmare to create and worse to maintain. – Joel Etherton Feb 09 '12 at 11:07
7

I know this is old but I ran across this recently. The best way I found to fix this is to modify YourProjectName.csproj file by adding the following:

<Target Name="ChangeAliasesOfStrongNameAssemblies" BeforeTargets="FindReferenceAssembliesForReferences;ResolveReferences">
    <ItemGroup>
        <ReferencePath Condition="'%(FileName)' == 'Namespace.You.Want.To.Alias'">
            <Aliases>NewAliasForNamespace</Aliases>
        </ReferencePath>
    </ItemGroup>
</Target>
Denis
  • 11,796
  • 16
  • 88
  • 150
1

you can use an aliases to the different namespaces and/or types:

here's how it would look like:

using other = sssssss.a;
namespace ConsoleApplication1
{
    public class a 
    {
        public string ff { get; set; }
    }
    class Program
    {
        static void Main(string[] args)
        {
            other s = new other();
            a b = new a();
        }
    }
}
namespace sssssss 
{

    public class a
    {
        public string ff { get; set; }
    }
}

MSDN

Igarioshka
  • 677
  • 3
  • 14
0

Maybe you can trick it, by changing a namespace of one of the assemblies, in this case fully qualified name of one COMMONTYPE will not be equal to another, and possibly it could resolve your problem with conflict occurring in the 3rd DLL.

Hope this helps.

M.Babcock
  • 18,753
  • 6
  • 54
  • 84
Tigran
  • 61,654
  • 8
  • 86
  • 123
  • Unfortunately I can't do that coz I'm generating the .NET assembly from an existing COM dll using tlbimp. – Kou S Hal Feb 09 '12 at 08:58