Инструменты .NET: Извлечение интерфейса и реализация класса Wrapper - PullRequest
6 голосов
/ 18 февраля 2011

Существует ли инструмент, который может генерировать извлечение и генерацию интерфейсов для существующих классов?

Я знаю Visual Studio извлечет интерфейс для существующего класса. Однако я также хотел бы создать класс-оболочку, который реализует эту функциональность.

Полагаю, это очень поможет при юнит-тестировании.

Пример существующего класса:

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();
   }
}

Обновление:

Это было бы особенно полезно для статических классов. Как указывает Мортен, я могу просто использовать заглушку, но я хотел бы по возможности разорвать соединение.

Ответы [ 5 ]

8 голосов
/ 28 ноября 2012

Нашли способ обойти это для незапечатанных классов.

1 - Наследовать от внешнего класса

class MyWrapper : ExternalClass

2 - Извлечение интерфейса для всех открытых методов

class MyWrapper : ExternalClass, IExternalClass

3 - убрать наследование из внешнего класса

class MyWrapper : IExternalClass

4 - Вы получите подсказку для имени класса о членах из интерфейса, который не реализован. Alt + Войдите в него и позвольте Resharper автоматически реализовать их

5 - Используйте этот шаблон кода для переноса свойств

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

6 - использовать этот шаблон кода для переноса методов

return $INNERCOMPONENT$.$NAME$($SIGNATURE$);
3 голосов
/ 18 февраля 2011

Я не знаю инструмент, который бы сделал это для вас.

Вы, наверное, знаете, но Visual Studio идет на полшага дальше - он может обеспечить пустую реализацию интерфейса.Я бы остановился на этом, если бы это было одноразовое задание.

В зависимости от фактической цели может работать другой способ - например, для тестирования вы можете использовать фальшивые рамки - обычно есть способ обернуть существующий класс и переопределить некоторые методыпо мере необходимости.

1 голос
/ 06 февраля 2015

Другой действительно удобный способ сделать это - использовать Resharper для генерации «делегирующих членов» для вас, как описано здесь: https://stackoverflow.com/a/2150827/1703887

Шаги:

  1. Создайте новый класс, который наследует от класса, который вы хотите обернуть, с помощью закрытой переменной этого типа:

    public class ThirdPartyClassWrapper : ThirdPartyClass
    {
        private ThirdPartyClass _ThirdPartyClass;
    }
    
  2. Сделайте Alt-Insert в / на классе, чтобы использоватьРешарпер для генерации «Делегирующих членов».Выберите методы, которые вы хотите предоставить, и перейдите к закрытой переменной.

  3. Если у вас установлена ​​бесплатная версия расширения GhostDoc , вы можете выделить всесозданные свойства, методы и т. д. и сделать Ctrl-D, чтобы автоматически извлечь всю документацию из базового класса и поместить ее в новых членов.(Resharper может сделать это тоже, но я думаю, что вам нужно будет поставить «новый» на каждый элемент, который затем позволит вам Alt-Enter и выбрать «Добавить комментарии xml-doc» из всплывающего меню Resharper).

  4. Затем можно удалить базовый класс и выполнить дополнительную очистку в случае, если сигнатуры метода / свойства предоставляют другие типы, которые необходимо обернуть.

0 голосов
/ 11 января 2017

Я настоятельно рекомендую вам взглянуть на такие насмешливые рамки, как Fakeiteasy.

Но чтобы дать вам именно то, о чем вы просили, см. Ниже.Я подозреваю, что у ReSharper не было этой операции, когда другие отвечали.

  1. добавьте интерфейс к классу, который вы хотите быть классом упаковки

    class MyWebElement : IWebElement { }
    

Найти / Нажать «Делегировать реализацию« YourInterfaceHere »в новое поле Delegate Implementation
Выберите параметры Delegate options

Нажмите «Готово» и наслаждайтесь новым классом

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; }
    }
}
0 голосов
/ 18 февраля 2011

То, что вы ищете, является заглушкой, это может быть сделано либо путем создания собственной реализации заглушки интерфейса, либо с помощью фреймворка, такого как Rhinomocks.Заключение сложного класса в другой класс для целей теста ничего хорошего для вас не дает.

С уважением, Мортен

...