【问题标题】:Auto-generate a Wrapper class in C# using Composition在 C# 中使用 Composition 自动生成 Wrapper 类
【发布时间】:2018-04-25 04:14:07
【问题描述】:

这应该很简单,但我找不到任何东西。

我在一个程序集中有一个类(一个共享库——它是一组 Web 服务的代理类) 我在另一个程序集(网络项目)中有一个类

代理程序集中有一个名为“Profile”的类。 在 Web 项目中有一组“使用”配置文件的类。 当没有用户登录时,使用 GenericProfile。

遵循“关注点分离”的原则...... 代理程序集由其他项目使用,并且只关心 Web 服务的东西。 该网络项目只是在其中包含网络内容

但是,现在需要“GenericProfile”——将其视为“Guest User”。

合乎逻辑的做法是构建一个名为 IProfile 的接口并让两个类都派生自它。但这会在两个程序集之间产生循环依赖。

下一个最佳想法是创建一个名为 MyInterfaces 的第三个程序集并将 IProfile 放入其中 - 但在我看来,这会导致违反关注点分离原则。至少,这个问题的一个实例似乎太小了,不足以在我的解决方案中创建一个额外的模块。

输入包装类——或者复合包装类(随便你怎么称呼它)

我正在寻找最终生成如下内容的内容。是否有工具或 Visual Studio 扩展可以做到这一点?也许是一个 .tt 文件?

namespace WebProject
{
   public interface IProfile
   {...}

   class MyWrapperClass : IProfile
   {
       Proxy.Profile _profile;

       public MyWrapperClass(Proxy.Profile proxy)
       {
           _profile = proxy;
       }

       public string IProfile.Property1{ get { return _profile.Property1; } set { _profile.Property1 = value; } }
       public string IProfile.Property2{ get { return _profile.Property2; } set { _profile.Property2 = value; } }
       public string IProfile.Property3{ get { return _profile.Property3; } set { _profile.Property3 = value; } }
   }

}

【问题讨论】:

  • 好像有人问过类似的问题...stackoverflow.com/questions/2150416/…
  • 虽然我没有 ReSharper...
  • 我会为此使用 T4(正如您所想的那样),但我不知道是否已经有一个完整的模板用于此。但我认为使用反射可以很容易地编写这样的模板。

标签: c# visual-studio


【解决方案1】:

在 Visual Studio 2017 中

创建你的类

namespace WebProject
{
   public interface IProfile
   {...}

   class MyWrapperClass : IProfile
   {
      private IProfile _wrapped;
   }
}

将光标定位在 MyWrapperClass 类的 IProfile 上:IProfile 并按 ctrl-。选择通过_wrapped实现接口。不需要 ReSharper。

【讨论】:

    【解决方案2】:

    我不完全理解您要完成的工作,但以下是我将如何使用 ReSharper 生成包装类。

    就我个人而言,如果我的雇主不想为 ReSharper 付费,我会购买。它使我成为一个更好的开发人员。我强烈建议您考虑将其作为对您职业生涯的投资。反免责声明 - 我与 ReSharper 没有任何联系或赞助。

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

      class MyWebElement : IWebElement { }
      

    1. 查找/单击“将“YourInterfaceHere”的实现委托给新字段

    1. 选择您的选项

    1. 点击完成,享受你的新课程

      class MyWebElement : IWebElement
      {
          private IWebElement _webElementImplementation;
          public IWebElement FindElement(By @by)
          {
              return _webElementImplementation.FindElement(@by);
          }
      
          public ReadOnlyCollection<IWebElement> 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; }
          }
      }
      

    【讨论】:

    • Visual Studio 开箱即用。根据我的经验,Resharper 在本世纪初曾经很出色,但 MS 很快就赶上了。安装 Resharper 现在只有负面影响。我知道这是非常主观的,不想挑起战争。这只是我作为高级开发人员的经验。
    • TheSoftwareJedi,请分享有关在没有 ReSharper 的情况下如何解决此问题的说明。旁注:我喜欢 Resharper 的格式以及它如何提示如何更有效地使用 c#。
    • 如果您的类实现了一个接口,并且有一个实例字段或属性,“快速操作”将包含一个选项来“通过”您的字段实现接口。请参阅下面有人已经给出的答案。
    【解决方案3】:

    如果我遇到了您最初的问题,我会将IProfileProfile 类放在您的共享库中。然后,您的 Web 项目可以实现它需要的 GenericProfile 类,无需了解其他任何信息,并且该库的其他客户端可以根据需要执行相同的操作。它对于测试库也很有用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-04-24
      • 1970-01-01
      • 2020-03-25
      • 1970-01-01
      • 2021-01-15
      • 1970-01-01
      • 2011-01-08
      相关资源
      最近更新 更多