Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Type exists in 2 assemblies

Tags:

c#

com-interop

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?

like image 851
Kou S Hal Avatar asked Feb 08 '12 13:02

Kou S Hal


5 Answers

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();
        }
    }
}
like image 76
Tom Avatar answered Nov 07 '22 15:11

Tom


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();
like image 44
Zunair Avatar answered Nov 07 '22 14:11

Zunair


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.

like image 14
Joel Etherton Avatar answered Nov 07 '22 14:11

Joel Etherton


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>
like image 4
Denis Avatar answered Nov 07 '22 16:11

Denis


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

like image 1
Igarioshka Avatar answered Nov 07 '22 15:11

Igarioshka