.NET工具:提取接口并实现包装类

是否有可以为现有类生成提取和生成接口的工具?

我知道Visual Studio将为现有类提取接口。 但是,我还想生成一个实现该function的包装类。

我相信这对unit testing非常有帮助。

示例现有类:

public class ThirdPartyClass { public void Method1(){} public void Method2(){} } 

这可以由Visual Studio(Extract Interface)生成:

 public interface IThirdPartyClass { void Method1(); void Method2(); } 

我想更进一步:

 public class ThirdPartyClassWrapper : IThirdPartyClass { private tpc = new ThirdPartyClass(); public void Method1() { tpc.Method1(); } public void Method2() { tpc.Method2(); } } 

更新:

这对静态类特别有用。 正如Morten所指出的那样,我可以使用存根,但是,如果可能的话,我想打破我的耦合。

为非密封类找到了解决方法。

1 – 从外部类inheritance

 class MyWrapper : ExternalClass 

2 – 提取所有公共方法的接口

 class MyWrapper : ExternalClass, IExternalClass 

3 – 从外部类中删除inheritance

 class MyWrapper : IExternalClass 

4 – 您将获得有关未实现的接口的成员的类名称的提示。 按住Alt + Enter并让Resharper自动实现它们

5 – 使用此代码模板来包装属性

  get { return $INNERCOMPONENT$.$NAME$; } set { $INNERCOMPONENT$.$NAME$ = value; } 

6 – 使用此代码模板来包装方法

 return $INNERCOMPONENT$.$NAME$($SIGNATURE$); 

我不知道哪种工具可以帮到你。

您可能知道,但Visual Studio只是前进了一步 – 它可以提供接口的空实现。 如果是一次性任务,我会在那里停下来。

根据实际目标,使用其他方式可能有效 – 即,对于测试,您可以使用模拟框架 – 通常有一种方法来包装现有类并根据需要覆盖某些方法。

另一个非常灵活的方法是使用Resharper为您生成“委派成员”,如下所述: https : //stackoverflow.com/a/2150827/1703887

脚步:

  1. 创建一个新类,该类inheritance自要用该类类型的私有变量包装的类:

     public class ThirdPartyClassWrapper : ThirdPartyClass { private ThirdPartyClass _ThirdPartyClass; } 
  2. 在类中/上执行Alt-Insert以使用Resharper生成“委派成员”。 选择要公开的方法并传递给私有变量。

  3. 如果您安装了免费版本的GhostDoc扩展 ,则可以突出显示所有已创建的属性,方法等,并执行Ctrl-D以自动获取基类中的所有文档并将其放在新成员上。 (Resharper也可以这样做,但我认为你必须在每个项目上添加“new”,然后允许你按Alt-Enter并从Resharper弹出菜单中选择“Add xml-doc comments”)。

  4. 然后,您可以删除基类并进行一些额外的清理,以防方法/属性签名暴露您需要包装的任何其他类型。

您正在寻找的是一个存根,这可以通过创建您自己的接口的存根实现,或通过使用像Rhinomocks这样的模拟框架来完成。 在另一个课程中为一个测试目的包装一个困难的课程对你没有任何好处。

关心莫滕

我强烈建议你研究像Fakeiteasy这样的模拟框架。

但要准确地告诉你你的要求,请参阅下文。 我怀疑当其他人回答时,ReSharper没有这个操作。

  1. 将接口添加到您希望成为包装类的类中

     class MyWebElement : IWebElement { } 

  1. 查找/单击“将”YouInterfaceHere“的实现委派给新字段 代表实施

  1. 选择您的选项 代表选项

  1. 点击完成并享受您的新课程

     class MyWebElement : IWebElement { private IWebElement _webElementImplementation; public IWebElement FindElement(By @by) { return _webElementImplementation.FindElement(@by); } public ReadOnlyCollection FindElements(By @by) { return _webElementImplementation.FindElements(@by); } public void Clear() { _webElementImplementation.Clear(); } public void SendKeys(string text) { _webElementImplementation.SendKeys(text); } public void Submit() { _webElementImplementation.Submit(); } public void Click() { _webElementImplementation.Click(); } public string GetAttribute(string attributeName) { return _webElementImplementation.GetAttribute(attributeName); } public string GetCssValue(string propertyName) { return _webElementImplementation.GetCssValue(propertyName); } public string TagName { get { return _webElementImplementation.TagName; } } public string Text { get { return _webElementImplementation.Text; } } public bool Enabled { get { return _webElementImplementation.Enabled; } } public bool Selected { get { return _webElementImplementation.Selected; } } public Point Location { get { return _webElementImplementation.Location; } } public Size Size { get { return _webElementImplementation.Size; } } public bool Displayed { get { return _webElementImplementation.Displayed; } } }