创建一个遗留库代码合同 [英] Create code contracts for a legacy library

查看:136
本文介绍了创建一个遗留库代码合同的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

的最终目标是要指定驻留在一个外部程序集,我没有控制权(即我不能只是补充合同,对该类直接)一类的合同。

The ultimate goal is to specify contracts for a class that resides in an external assembly that I don't have control over (i.e. I cannot just add contracts to that class directly).

我迄今为止尝试:


  1. ContractClassFor 属性。结果
    不工作,因为目标类必须指向回合同类。

  1. ContractClassFor attribute.
    Doesn't work, because the target class must point back to the contract class.

手动构建通过反向设计自动生成的那些合同基准组件(即MyAsm.Contracts.dll)。结果
不的工作,因为之后我编译它,在重写踢和方便剥掉了 ContractDeclarativeAssembly 属性,这使得装配的工具合同参考汇编面目全非。我不能找到一个办法把重写了。

Manually construct a contract reference assembly (i.e. MyAsm.Contracts.dll) by reverse-engineering the autogenerated ones.
Doesn't work, because right after I compile it, the rewriter kicks in and conveniently strips off the ContractDeclarativeAssembly attribute, which makes the assembly unrecognizable by the tools as "contract reference assembly". And I cannot find a way to turn the rewriter off.

创建具有相同的名称,版本,强名称(如果有的话)和其他属性作为目标装配一个假集会,并把同名类与有相同名称的方法。然后编译建合同指针装配选项打开,然后取生成的合同参考组装和使用它。结果
这也没有出于某种原因,虽然我不知道这个理由正是。静态检查完全忽视我的聪明的家伙产生的参考组装,就好像它不存在。

Create a "fake" assembly with same name, version, strong name (if any) and other attributes as the target assembly, and put same-named classes with same-named methods in there. Then compile that assembly with "build contract reference" option turned on, then take the generated contract reference assembly and use it.
This also didn't work for some reason, although I have no idea what that reason was exactly. The static checker simply ignores my smartypants-generated reference assembly, as if it didn't exist.

还有一东西,以防万一它事项:目标组件编译为.NET 2.0,我不能重新编译为4.0

And one more thing, just in case it matters: the target assembly is compiled for .NET 2.0, and I cannot recompile it for 4.0.

更新

编写一个包装库定义的合同是毫无疑问的。

Writing a "wrapper" library with defined contracts is out of question.

有关的,这是一个很多额外的代码来写。但是,即使你离开那一边,它可能是一个显著的性能损失:我会(可能)创建一个用作返回类型从我的传统方法每一个遗留类型的包装类。但是,即使这不是故事的结束。试想一下,有些方法可能返回引用到基本接口,然后调用代码可以将它们转换成导出接口,看是否对象支持更多的功能。我该如何包装的?我可能会定制提供演员LT; T>()我的包装类,将尝试投基础类/接口,并返回一个包装器,如果成功的结果的方法。最后,我的整个代码库会变得如此错综复杂,它可能不值得也无妨。

For one, it's a lot of extra code to write. But even if you leave that aside, it may be a significant performance penalty: I would have to (potentially) create wrapper classes for every "legacy" type that is used as return type from my "legacy" methods. But even that is not the end of the story. Imagine that some methods may return references to base interfaces, and then the calling code might cast them to derived interfaces to see if the object supports more functionality. How do I wrap those? I would probably have to provide custom Cast<T>() methods on my wrapping classes, which will try to cast the underlying class/interface and return a wrapper for result if successful. In the end, my whole codebase will become so convoluted that it's probably not worth it anyway.

在另一方面,正是这个问题已经成功地由CC解决团队本身:他们做适当的运合同基准组件的mscorlib程序,System.Core程序和其他一些系统组件,不是吗?他们是怎么建立呢?如果他们能做到这一点的话,我看不出有任何理由为什么我不应该能够拉过同样的伎俩。

On the other hand, precisely this problem has already been successfully solved by the CC team itself: they do ship proper contract reference assemblies for mscorlib, System.Core and some other system assemblies, don't they? How did they manage to build them? If they can do it, then I don't see any reason why I shouldn't be able to pull off the same trick.

呵呵,好了,其实,我也看到一个原因:我不知道该怎么做。 :-) - 费奥多尔Soikin 18秒前修改

Oh, well, actually, I do see one reason: I don't know how to do it. :-) – Fyodor Soikin 18 secs ago edit

推荐答案

您很可能几乎没有与(2)。一定要关掉合同重写为C#程序集你手工构建。关闭所有运行时检查和静态分析和重新作家不应该踢。把它放在任何地方所有其他CodeContracts组件去,例如对于/bin/X.dll,做出去/bin/CodeContracts/X.Contracts.dll组装

You were probably almost there with (2). Be sure to turn off contract re-writing for the C# assembly you construct by hand. Turn off all run-time checking and static analysis and the re-writer shouldn't kick in. Put it wherever all your other CodeContracts assemblies are going, e.g. for /bin/X.dll, make an assembly that goes to /bin/CodeContracts/X.Contracts.dll.

请参阅 http://social.msdn.microsoft.com/Forums/en-美国/ codecontracts /线程/ 5fe7ad4e-d4f1-4bb5-806e-a1e31f550181 。你是对的 - 只是看着反射创建了所有正确的位,它的作品了。我想这样做是为了合同添加到我的F#组件,直至F#可以处理合同。

See http://social.msdn.microsoft.com/Forums/en-US/codecontracts/thread/5fe7ad4e-d4f1-4bb5-806e-a1e31f550181. You were right -- just create all the right bits by looking at Reflector and it works out. I wanted to do this to add contracts to my F# assembly until F# can handle contracts.

这篇关于创建一个遗留库代码合同的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆