Error rewriting the contract code with the error "Failed to resolve the participant link"

Please note that this may be a duplicate of this question , I'm not quite sure.

My problem is that I have a class library project that has a link to a third-party library (COM) library. I want to put contracts in methods in a class library, for example:

public class foo { public static int divide(TypeFromTypeLib tftl, int a, int b) { Contract.Requires<ArgumentException>(b != 0); return a / b; } } 

And then use a client project like

 var n = foo.divide(null, 4, 2); 

But I would also like the client project to also use contracts in some of its methods. Thus, I set the Code Contracts properties for both projects to “Run Runtime Execution Checks” (without which you get a runtime assert statement indicating that it needs this setting).

Now, when I try to compile the client, I get the following error:

Could not find item reference: my_class_lib.foo::divide.

ccrewrite: error: overwrite due to metadata errors.

What seems inevitable - at any time when a method is called that has a type from a library of a third-party type, this happens. Remove this type from the method signature and that will be fine.

Can anyone explain why this is happening? Is this the key to the fact that the structure of my code is fundamentally wrong (if so, why?), Or is it a fad of code contracts? Is there a recommended fix for this problem?

+7
c # code-contracts
source share
1 answer

Honestly, I don't know why ccrewrite has a problem with interop types, but I can give you 3 workarounds:

Solution 1

This is one of the simplest:

  • Go to the list of links for the project.
  • Find a third-party type library.
  • Right click.
  • In the context menu, select "Properties."
  • Change attachments of interaction types from True to False.

You must do this for both projects. The disadvantage of this solution is that after the assembly, you will get an additional interop assembly in the bin folder.

Decision 2

Another solution might be to remove types from a third-party type library from the open ie interface:

 public class foo { public static int divide(int a, int b) { return divide(null, a, b); } private static int divide(TypeFromTypeLib tftl, int a, int b) { Contract.Requires<ArgumentException>(b != 0); return a / b; } } 

Of course, you can only do this if you do not need to use TypeFromTypeLib in your client.

Decision 3

If you need to use TypeFromTypeLib in your client, you can write a wrapper for this ie class:

 public class MyTypeFromTypeLib { //... } public class foo { public static int divide(MyTypeFromTypeLib mytftl, int a, int b) { var tftl = new TypeFromTypeLib(); //Map MyTypeFromTypeLib to TypeFromTypeLib //... return divide(tftl , a, b); } private static int divide(TypeFromTypeLib tftl, int a, int b) { Contract.Requires<ArgumentException>(b != 0); return a / b; } } 

However, this solution is cumbersome because additional classes are needed.

+2
source share

All Articles