How to use the type equivalence feature in .NET?2019 Community Moderator ElectionHow do I calculate someone's age in C#?Hidden Features of C#?How do I enumerate an enum in C#?How do I get a consistent byte representation of strings in C# without manually specifying an encoding?Difference between decimal, float and double in .NET?Interop type cannot be embeddedWhat is a NullReferenceException, and how do I fix it?Type or namespace name does not existThe type or namespace name does not exist in the namespace 'System.Web.Mvc'Could not find a part of the path … binroslyncsc.exe

Can anyone tell me why this program fails?

How to make healing in an exploration game interesting

Russian cases: A few examples, I'm really confused

Possible Leak In Concrete

How to simplify this time periods definition interface?

Does the statement `int val = (++i > ++j) ? ++i : ++j;` invoke undefined behavior?

How to deal with taxi scam when on vacation?

Is it possible that AIC = BIC?

What does it mean to make a bootable LiveUSB?

Why is "das Weib" grammatically neuter?

Old race car problem/puzzle

Is it true that real estate prices mainly go up?

What are the possible solutions of the given equation?

Identifying the interval from A♭ to D♯

Make a transparent 448*448 image

Why are the outputs of printf and std::cout different

The use of "touch" and "touch on" in context

Why doesn't the EU now just force the UK to choose between referendum and no-deal?

Welcoming 2019 Pi day: How to draw the letter π?

Can elves maintain concentration in a trance?

How to deal with a cynical class?

Is a lawful good "antagonist" effective?

My adviser wants to be the first author

How could a scammer know the apps on my phone / iTunes account?



How to use the type equivalence feature in .NET?



2019 Community Moderator ElectionHow do I calculate someone's age in C#?Hidden Features of C#?How do I enumerate an enum in C#?How do I get a consistent byte representation of strings in C# without manually specifying an encoding?Difference between decimal, float and double in .NET?Interop type cannot be embeddedWhat is a NullReferenceException, and how do I fix it?Type or namespace name does not existThe type or namespace name does not exist in the namespace 'System.Web.Mvc'Could not find a part of the path … binroslyncsc.exe










5















I am trying to understand the type equivalence feature of .NET. I created three projects in a solution, two libraries and one console application.



In the libraries I have defined these types:



ClassLibrary1:



namespace ClassLibrary1

[TypeIdentifier("scope1", "identifier1")]
public interface IInterface1






ClassLibrary2:



namespace ClassLibrary2

[TypeIdentifier("scope1", "identifier1")]
public interface IInterface1






I did this based on the documentation here:
https://docs.microsoft.com/en-us/dotnet/framework/interop/type-equivalence-and-embedded-interop-types



And in the console application:



static void Main(string[] args)

ClassLibrary1.IInterface1 variable1 = null;

ClassLibrary2.IInterface1 variable2 = null;

variable1 = variable2;



I am getting these compilation error:



Error CS0234 The type or namespace name 'IInterface1' does not exist in the namespace 'ClassLibrary2' (are you missing an assembly reference?)



Error CS0234 The type or namespace name 'IInterface1' does not exist in the namespace 'ClassLibrary1' (are you missing an assembly reference?)



If remove the TypeIdentifier attribute from the interface definitions, these two errors go away, but of course the compiler wouldn't allow the variable assignments because these are different types.



My question is why do the types seem to disappear if I annotate them with the TypeIdentifier attribute? And how to use type equivalence in .NET?



UPDATE: I tried to reference the libraries as DLLs instead of projects and I get the same result.



UPDATE:



I was able to make type equivalence work in both the .NET framework and .NET Core 3.



Source code can be found here: https://github.com/ymassad/TypeEquivalenceExample



So my current understanding is that the TypeIdentifier attribute is not supposed to be used by developers directly.



When project A references project B, it can specify that it wants to "Embed Interop Types". There are certain conditions for this to work, but the result is that types from B that are used in A are copied inside the Assembly generated when compiling A. These types will be annotated with this attribute by the compiler. It seems that this feature is specifically designed to enable .NET apps to use COM types without the need to deploy an assembly called the "Primary Interop Assembly". This PIA assembly contains all the metadata required to speak with a certain COM based library. If an application/library requires only a few types from this library, it can choose to embed just these types inside itself. Type equivalence is needed here so that different types embedded in different assemblies can be used interchangeably.



I cannot find any documentation explaining why using this feature in the direct way I am describing in this question cannot work. I would appreciate if someone can shed some light on this. Is there a way to make things work in the way described by this question?










share|improve this question



















  • 1





    I'm curious why you are even trying to do this? This was useful in the days of COM but I've not seen it used for a very long time.

    – DavidG
    Mar 7 at 10:52











  • @DavidG, this is a potential solution for a problem that I am trying to solve. The problem is to big to present here. Based on the fact that COM interfaces embedded in different assemblies can be used interchangeably, I wondered if I can use this feature outside of COM.

    – Yacoub Massad
    Mar 7 at 12:09











  • Well without your specific use case it's hard to suggest alternatives. The usual option would be to have classes in their own DLL and share that around, that usually makes all this go away. Or use a mapping tool like AutoMapper. Of course this might not be useful in your situation.

    – DavidG
    Mar 7 at 12:11











  • @DavidG, that wouldn't be useful in my situation. Since this is a documented feature, I expect this to work. I wonder if the feature is intentionally disabled for non-COM scenarios.

    – Yacoub Massad
    Mar 7 at 12:13











  • @YacoubMassad: It's a documented feature in terms of COM types. The documentation refers to COM types all over the place, e.g. "Equivalence of COM types is supported for interfaces, structures, enumerations, and delegates." I don't think it's reasonable to expect it to work for non-COM types, given the heavy emphasis of COM in all the documentation. I would strongly advise you to look for a different solution to whatever your original problem is. (We can't give advice on how to solve the problem, as all we know is how you're already trying to solve it in a way that doesn't work.)

    – Jon Skeet
    Mar 9 at 9:58
















5















I am trying to understand the type equivalence feature of .NET. I created three projects in a solution, two libraries and one console application.



In the libraries I have defined these types:



ClassLibrary1:



namespace ClassLibrary1

[TypeIdentifier("scope1", "identifier1")]
public interface IInterface1






ClassLibrary2:



namespace ClassLibrary2

[TypeIdentifier("scope1", "identifier1")]
public interface IInterface1






I did this based on the documentation here:
https://docs.microsoft.com/en-us/dotnet/framework/interop/type-equivalence-and-embedded-interop-types



And in the console application:



static void Main(string[] args)

ClassLibrary1.IInterface1 variable1 = null;

ClassLibrary2.IInterface1 variable2 = null;

variable1 = variable2;



I am getting these compilation error:



Error CS0234 The type or namespace name 'IInterface1' does not exist in the namespace 'ClassLibrary2' (are you missing an assembly reference?)



Error CS0234 The type or namespace name 'IInterface1' does not exist in the namespace 'ClassLibrary1' (are you missing an assembly reference?)



If remove the TypeIdentifier attribute from the interface definitions, these two errors go away, but of course the compiler wouldn't allow the variable assignments because these are different types.



My question is why do the types seem to disappear if I annotate them with the TypeIdentifier attribute? And how to use type equivalence in .NET?



UPDATE: I tried to reference the libraries as DLLs instead of projects and I get the same result.



UPDATE:



I was able to make type equivalence work in both the .NET framework and .NET Core 3.



Source code can be found here: https://github.com/ymassad/TypeEquivalenceExample



So my current understanding is that the TypeIdentifier attribute is not supposed to be used by developers directly.



When project A references project B, it can specify that it wants to "Embed Interop Types". There are certain conditions for this to work, but the result is that types from B that are used in A are copied inside the Assembly generated when compiling A. These types will be annotated with this attribute by the compiler. It seems that this feature is specifically designed to enable .NET apps to use COM types without the need to deploy an assembly called the "Primary Interop Assembly". This PIA assembly contains all the metadata required to speak with a certain COM based library. If an application/library requires only a few types from this library, it can choose to embed just these types inside itself. Type equivalence is needed here so that different types embedded in different assemblies can be used interchangeably.



I cannot find any documentation explaining why using this feature in the direct way I am describing in this question cannot work. I would appreciate if someone can shed some light on this. Is there a way to make things work in the way described by this question?










share|improve this question



















  • 1





    I'm curious why you are even trying to do this? This was useful in the days of COM but I've not seen it used for a very long time.

    – DavidG
    Mar 7 at 10:52











  • @DavidG, this is a potential solution for a problem that I am trying to solve. The problem is to big to present here. Based on the fact that COM interfaces embedded in different assemblies can be used interchangeably, I wondered if I can use this feature outside of COM.

    – Yacoub Massad
    Mar 7 at 12:09











  • Well without your specific use case it's hard to suggest alternatives. The usual option would be to have classes in their own DLL and share that around, that usually makes all this go away. Or use a mapping tool like AutoMapper. Of course this might not be useful in your situation.

    – DavidG
    Mar 7 at 12:11











  • @DavidG, that wouldn't be useful in my situation. Since this is a documented feature, I expect this to work. I wonder if the feature is intentionally disabled for non-COM scenarios.

    – Yacoub Massad
    Mar 7 at 12:13











  • @YacoubMassad: It's a documented feature in terms of COM types. The documentation refers to COM types all over the place, e.g. "Equivalence of COM types is supported for interfaces, structures, enumerations, and delegates." I don't think it's reasonable to expect it to work for non-COM types, given the heavy emphasis of COM in all the documentation. I would strongly advise you to look for a different solution to whatever your original problem is. (We can't give advice on how to solve the problem, as all we know is how you're already trying to solve it in a way that doesn't work.)

    – Jon Skeet
    Mar 9 at 9:58














5












5








5








I am trying to understand the type equivalence feature of .NET. I created three projects in a solution, two libraries and one console application.



In the libraries I have defined these types:



ClassLibrary1:



namespace ClassLibrary1

[TypeIdentifier("scope1", "identifier1")]
public interface IInterface1






ClassLibrary2:



namespace ClassLibrary2

[TypeIdentifier("scope1", "identifier1")]
public interface IInterface1






I did this based on the documentation here:
https://docs.microsoft.com/en-us/dotnet/framework/interop/type-equivalence-and-embedded-interop-types



And in the console application:



static void Main(string[] args)

ClassLibrary1.IInterface1 variable1 = null;

ClassLibrary2.IInterface1 variable2 = null;

variable1 = variable2;



I am getting these compilation error:



Error CS0234 The type or namespace name 'IInterface1' does not exist in the namespace 'ClassLibrary2' (are you missing an assembly reference?)



Error CS0234 The type or namespace name 'IInterface1' does not exist in the namespace 'ClassLibrary1' (are you missing an assembly reference?)



If remove the TypeIdentifier attribute from the interface definitions, these two errors go away, but of course the compiler wouldn't allow the variable assignments because these are different types.



My question is why do the types seem to disappear if I annotate them with the TypeIdentifier attribute? And how to use type equivalence in .NET?



UPDATE: I tried to reference the libraries as DLLs instead of projects and I get the same result.



UPDATE:



I was able to make type equivalence work in both the .NET framework and .NET Core 3.



Source code can be found here: https://github.com/ymassad/TypeEquivalenceExample



So my current understanding is that the TypeIdentifier attribute is not supposed to be used by developers directly.



When project A references project B, it can specify that it wants to "Embed Interop Types". There are certain conditions for this to work, but the result is that types from B that are used in A are copied inside the Assembly generated when compiling A. These types will be annotated with this attribute by the compiler. It seems that this feature is specifically designed to enable .NET apps to use COM types without the need to deploy an assembly called the "Primary Interop Assembly". This PIA assembly contains all the metadata required to speak with a certain COM based library. If an application/library requires only a few types from this library, it can choose to embed just these types inside itself. Type equivalence is needed here so that different types embedded in different assemblies can be used interchangeably.



I cannot find any documentation explaining why using this feature in the direct way I am describing in this question cannot work. I would appreciate if someone can shed some light on this. Is there a way to make things work in the way described by this question?










share|improve this question
















I am trying to understand the type equivalence feature of .NET. I created three projects in a solution, two libraries and one console application.



In the libraries I have defined these types:



ClassLibrary1:



namespace ClassLibrary1

[TypeIdentifier("scope1", "identifier1")]
public interface IInterface1






ClassLibrary2:



namespace ClassLibrary2

[TypeIdentifier("scope1", "identifier1")]
public interface IInterface1






I did this based on the documentation here:
https://docs.microsoft.com/en-us/dotnet/framework/interop/type-equivalence-and-embedded-interop-types



And in the console application:



static void Main(string[] args)

ClassLibrary1.IInterface1 variable1 = null;

ClassLibrary2.IInterface1 variable2 = null;

variable1 = variable2;



I am getting these compilation error:



Error CS0234 The type or namespace name 'IInterface1' does not exist in the namespace 'ClassLibrary2' (are you missing an assembly reference?)



Error CS0234 The type or namespace name 'IInterface1' does not exist in the namespace 'ClassLibrary1' (are you missing an assembly reference?)



If remove the TypeIdentifier attribute from the interface definitions, these two errors go away, but of course the compiler wouldn't allow the variable assignments because these are different types.



My question is why do the types seem to disappear if I annotate them with the TypeIdentifier attribute? And how to use type equivalence in .NET?



UPDATE: I tried to reference the libraries as DLLs instead of projects and I get the same result.



UPDATE:



I was able to make type equivalence work in both the .NET framework and .NET Core 3.



Source code can be found here: https://github.com/ymassad/TypeEquivalenceExample



So my current understanding is that the TypeIdentifier attribute is not supposed to be used by developers directly.



When project A references project B, it can specify that it wants to "Embed Interop Types". There are certain conditions for this to work, but the result is that types from B that are used in A are copied inside the Assembly generated when compiling A. These types will be annotated with this attribute by the compiler. It seems that this feature is specifically designed to enable .NET apps to use COM types without the need to deploy an assembly called the "Primary Interop Assembly". This PIA assembly contains all the metadata required to speak with a certain COM based library. If an application/library requires only a few types from this library, it can choose to embed just these types inside itself. Type equivalence is needed here so that different types embedded in different assemblies can be used interchangeably.



I cannot find any documentation explaining why using this feature in the direct way I am describing in this question cannot work. I would appreciate if someone can shed some light on this. Is there a way to make things work in the way described by this question?







c# .net clr






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Mar 9 at 9:39







Yacoub Massad

















asked Mar 7 at 10:43









Yacoub MassadYacoub Massad

23.8k21944




23.8k21944







  • 1





    I'm curious why you are even trying to do this? This was useful in the days of COM but I've not seen it used for a very long time.

    – DavidG
    Mar 7 at 10:52











  • @DavidG, this is a potential solution for a problem that I am trying to solve. The problem is to big to present here. Based on the fact that COM interfaces embedded in different assemblies can be used interchangeably, I wondered if I can use this feature outside of COM.

    – Yacoub Massad
    Mar 7 at 12:09











  • Well without your specific use case it's hard to suggest alternatives. The usual option would be to have classes in their own DLL and share that around, that usually makes all this go away. Or use a mapping tool like AutoMapper. Of course this might not be useful in your situation.

    – DavidG
    Mar 7 at 12:11











  • @DavidG, that wouldn't be useful in my situation. Since this is a documented feature, I expect this to work. I wonder if the feature is intentionally disabled for non-COM scenarios.

    – Yacoub Massad
    Mar 7 at 12:13











  • @YacoubMassad: It's a documented feature in terms of COM types. The documentation refers to COM types all over the place, e.g. "Equivalence of COM types is supported for interfaces, structures, enumerations, and delegates." I don't think it's reasonable to expect it to work for non-COM types, given the heavy emphasis of COM in all the documentation. I would strongly advise you to look for a different solution to whatever your original problem is. (We can't give advice on how to solve the problem, as all we know is how you're already trying to solve it in a way that doesn't work.)

    – Jon Skeet
    Mar 9 at 9:58













  • 1





    I'm curious why you are even trying to do this? This was useful in the days of COM but I've not seen it used for a very long time.

    – DavidG
    Mar 7 at 10:52











  • @DavidG, this is a potential solution for a problem that I am trying to solve. The problem is to big to present here. Based on the fact that COM interfaces embedded in different assemblies can be used interchangeably, I wondered if I can use this feature outside of COM.

    – Yacoub Massad
    Mar 7 at 12:09











  • Well without your specific use case it's hard to suggest alternatives. The usual option would be to have classes in their own DLL and share that around, that usually makes all this go away. Or use a mapping tool like AutoMapper. Of course this might not be useful in your situation.

    – DavidG
    Mar 7 at 12:11











  • @DavidG, that wouldn't be useful in my situation. Since this is a documented feature, I expect this to work. I wonder if the feature is intentionally disabled for non-COM scenarios.

    – Yacoub Massad
    Mar 7 at 12:13











  • @YacoubMassad: It's a documented feature in terms of COM types. The documentation refers to COM types all over the place, e.g. "Equivalence of COM types is supported for interfaces, structures, enumerations, and delegates." I don't think it's reasonable to expect it to work for non-COM types, given the heavy emphasis of COM in all the documentation. I would strongly advise you to look for a different solution to whatever your original problem is. (We can't give advice on how to solve the problem, as all we know is how you're already trying to solve it in a way that doesn't work.)

    – Jon Skeet
    Mar 9 at 9:58








1




1





I'm curious why you are even trying to do this? This was useful in the days of COM but I've not seen it used for a very long time.

– DavidG
Mar 7 at 10:52





I'm curious why you are even trying to do this? This was useful in the days of COM but I've not seen it used for a very long time.

– DavidG
Mar 7 at 10:52













@DavidG, this is a potential solution for a problem that I am trying to solve. The problem is to big to present here. Based on the fact that COM interfaces embedded in different assemblies can be used interchangeably, I wondered if I can use this feature outside of COM.

– Yacoub Massad
Mar 7 at 12:09





@DavidG, this is a potential solution for a problem that I am trying to solve. The problem is to big to present here. Based on the fact that COM interfaces embedded in different assemblies can be used interchangeably, I wondered if I can use this feature outside of COM.

– Yacoub Massad
Mar 7 at 12:09













Well without your specific use case it's hard to suggest alternatives. The usual option would be to have classes in their own DLL and share that around, that usually makes all this go away. Or use a mapping tool like AutoMapper. Of course this might not be useful in your situation.

– DavidG
Mar 7 at 12:11





Well without your specific use case it's hard to suggest alternatives. The usual option would be to have classes in their own DLL and share that around, that usually makes all this go away. Or use a mapping tool like AutoMapper. Of course this might not be useful in your situation.

– DavidG
Mar 7 at 12:11













@DavidG, that wouldn't be useful in my situation. Since this is a documented feature, I expect this to work. I wonder if the feature is intentionally disabled for non-COM scenarios.

– Yacoub Massad
Mar 7 at 12:13





@DavidG, that wouldn't be useful in my situation. Since this is a documented feature, I expect this to work. I wonder if the feature is intentionally disabled for non-COM scenarios.

– Yacoub Massad
Mar 7 at 12:13













@YacoubMassad: It's a documented feature in terms of COM types. The documentation refers to COM types all over the place, e.g. "Equivalence of COM types is supported for interfaces, structures, enumerations, and delegates." I don't think it's reasonable to expect it to work for non-COM types, given the heavy emphasis of COM in all the documentation. I would strongly advise you to look for a different solution to whatever your original problem is. (We can't give advice on how to solve the problem, as all we know is how you're already trying to solve it in a way that doesn't work.)

– Jon Skeet
Mar 9 at 9:58






@YacoubMassad: It's a documented feature in terms of COM types. The documentation refers to COM types all over the place, e.g. "Equivalence of COM types is supported for interfaces, structures, enumerations, and delegates." I don't think it's reasonable to expect it to work for non-COM types, given the heavy emphasis of COM in all the documentation. I would strongly advise you to look for a different solution to whatever your original problem is. (We can't give advice on how to solve the problem, as all we know is how you're already trying to solve it in a way that doesn't work.)

– Jon Skeet
Mar 9 at 9:58













0






active

oldest

votes











Your Answer






StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");

StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);













draft saved

draft discarded


















StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55041852%2fhow-to-use-the-type-equivalence-feature-in-net%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown

























0






active

oldest

votes








0






active

oldest

votes









active

oldest

votes






active

oldest

votes















draft saved

draft discarded
















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid


  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55041852%2fhow-to-use-the-type-equivalence-feature-in-net%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Can't initialize raids on a new ASUS Prime B360M-A motherboard2019 Community Moderator ElectionSimilar to RAID config yet more like mirroring solution?Can't get motherboard serial numberWhy does the BIOS entry point start with a WBINVD instruction?UEFI performance Asus Maximus V Extreme

Identity Server 4 is not redirecting to Angular app after login2019 Community Moderator ElectionIdentity Server 4 and dockerIdentityserver implicit flow unauthorized_clientIdentityServer Hybrid Flow - Access Token is null after user successful loginIdentity Server to MVC client : Page Redirect After loginLogin with Steam OpenId(oidc-client-js)Identity Server 4+.NET Core 2.0 + IdentityIdentityServer4 post-login redirect not working in Edge browserCall to IdentityServer4 generates System.NullReferenceException: Object reference not set to an instance of an objectIdentityServer4 without HTTPS not workingHow to get Authorization code from identity server without login form

2005 Ahvaz unrest Contents Background Causes Casualties Aftermath See also References Navigation menue"At Least 10 Are Killed by Bombs in Iran""Iran"Archived"Arab-Iranians in Iran to make April 15 'Day of Fury'"State of Mind, State of Order: Reactions to Ethnic Unrest in the Islamic Republic of Iran.10.1111/j.1754-9469.2008.00028.x"Iran hangs Arab separatists"Iran Overview from ArchivedConstitution of the Islamic Republic of Iran"Tehran puzzled by forged 'riots' letter""Iran and its minorities: Down in the second class""Iran: Handling Of Ahvaz Unrest Could End With Televised Confessions""Bombings Rock Iran Ahead of Election""Five die in Iran ethnic clashes""Iran: Need for restraint as anniversary of unrest in Khuzestan approaches"Archived"Iranian Sunni protesters killed in clashes with security forces"Archived