c# - .NET Code Contracts - ProjectA.exe cannot find ProjectB.Contracts.dll when both are in same solution -
i have c# solution in vs2013, code contracts extension installed. in solution have application project (projecta) , class library project (projectb). projecta references projectb, , of projectb's public members have contracts associated them.
i can access of projectb's members projecta without issue, on 1 property getting filenotfoundexception
, message "could not load file or assembly 'projectb.contracts, version=....' or 1 of dependencies."
here fusion log has say:
=== pre-bind state information ===
log: displayname = [solutionname].projectb.contracts, version=1.0.5953.23121, culture=neutral, publickeytoken=null (fully-specified)
log: appbase = [solutiondir]/[solutionname].projecta/bin/debug/
log: initial privatepath = null calling assembly : [solutionname].projectc, version=1.0.5953.23122, culture=neutral, publickeytoken=null.
xxx
log: bind starts in default load context.
log: using application configuration file: [mydocuments][solutionname][solutionname].projecta\bin\debug[solutionname].projecta.vshost.exe.config
log: using host configuration file:
log: using machine configuration file c:\windows\microsoft.net\framework64\v4.0.30319\config\machine.config.
log: policy not being applied reference @ time (private, custom, partial, or location-based assembly bind).
log: attempting download of new url [solutiondir]/[solutionname].projecta/bin/debug/[solutionname].projectb.contracts.dll.
log: attempting download of new url [solutiondir]/[solutionname].projecta/bin/debug/[solutionname].projectb.contracts/[solutionname].projectb.contracts.dll.
log: attempting download of new url [solutiondir]/[solutionname].projecta/bin/debug/[solutionname].projectb.contracts.exe.
log: attempting download of new url [solutiondir]/[solutionname].projecta/bin/debug/[solutionname].projectb.contracts/[solutionname].projectb.contracts.exe.
the references in solution standard framework libraries, other projects in solution, , 1 other first-party library (which references system.dll). i've tried cleaning , rebuilding projects in solution, other first-party library.
i confused several reasons.
- in output window, can see of projecta , projectb's references (and references) have been loaded.
- other seemingly similar methods , properties similar contracts not causing issues. also, i've been using code contracts months in several solutions , haven't run yet.
- shouldn't contract code recompiled projectb.dll? why projecta need know there .contracts library? (other intellisense , static analysis)
does know might going on here?
edit: projects in solution targeting .net 4.0 , "any cpu".
here few things tried didn't work:
on project settings projecta, on code contracts tab, tried adding ...projectb\bin\debug\codecontracts field extra contract library paths. did not change anything.
i tried manually adding reference projectb.contacts.dll. turned filenotfoundexception
missingmethodexception
. made me think issue perhaps due error code contracts rewriter. enter ilspy.
the contract causing issue in original source code:
contract.requires<argumentnullexception>(collection.all(x => x != null));
but had put in contract abbreviator method this:
public static class precondition { [contractabbreviator] public static void notisorhasnull<t>(ienumerable<t> collection){ contract.requires<argumentnullexception(collection != null, "collection cannot null."); contract.requires<argumentnullexception>(collection.all(x => x != null), "collection cannot contain null."); } }
and called in class this:
public class class1{ public void dostuff(ienumerable<t> collection){ precondition.notisorhasnull(collection); foreach (var x in collection){ //stuff } } }
when viewing troublesome method call in ilspy, saw trying call instance method named class1.notisorhasnull
, instead of static method precondition.notisorhasnull
.
the solution:
i changed precondition
class move linq expression own pure
function, , change contract abbreviator call method.
public static class precondition { [pure] public static boolean collectioncontainsnull(ienumerable<t> collection){ contract.requires<argumentnullexception(collection != null); if (typeof(t).isvaluetype) return false; return collection.any(x => object.equals(x, null)); } [contractabbreviator] public static void notisorhasnull<t>(ienumerable<t> collection){ contract.requires<argumentnullexception(collection != null, "collection cannot null."); contract.requires<argumentnullexception>(!collectioncontainsnull(collection)), "collection cannot contain null."); } }
now method call in class1
works , il looks correct in ilspy.
+1 ilspy!
Comments
Post a Comment