2011-02-17 16 views
5

¿Existe alguna herramienta que pueda generar interfaces de extracción y generación para clases existentes?Herramientas .NET: Extraiga la interfaz e implemente la clase Wrapper

Visual Studio extraerá una interfaz para una clase existente. Sin embargo, también me gustaría generar una clase contenedora que implemente esa funcionalidad.

Creo que esto ayudaría tremendamente para las pruebas unitarias.

Ejemplo clase existente:

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

Esto puede ser generado por Studio (Interfaz Extracto) Visual:

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

me gustaría ir un paso más allá:

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

Actualización:

Esto sería especialmente útil para las clases estáticas. Como señala Morten, puedo usar un trozo, sin embargo, me gustaría romper mi acoplamiento si es posible.

+1

alguna solución al respecto ?? – Kiquenet

+0

Encontré aquí en busca de la misma respuesta exacta. Estoy votando la pregunta. – Jazz

+0

Upvoting nuevamente. EF o VS deberían tener esta opción. – NoobDeveloper

Respuesta

3

No conozco una herramienta que pueda hacer eso por usted.

Probablemente lo sepa, pero Visual Studio va solo medio paso más allá: puede proporcionar una implementación vacía de la interfaz. Me detendría allí si es una tarea de una sola vez.

Dependiendo del objetivo real, usar de alguna otra manera puede funcionar, es decir, para probar puede usar marcos de burla, generalmente hay una manera de ajustar la clase existente y anular algunos métodos según sea necesario.

0

Lo que está buscando es un apéndice, esto puede hacerse ya sea al hacer su propia implementación de trozo de la interfaz, o mediante el uso de un marco de burla como Rhinomocks. Envolver una clase difícil en otra clase para fines de prueba no te sirve de nada.

Regards Morten

+0

"Envolver una clase difícil en otra clase para propósitos de prueba no hace nada bueno para usted". Creo que reduciría el acoplamiento y permitiría una implementación personalizada más adelante. –

+0

Sí, pero ¿por qué no solo resguardar la interfaz por ahora, y dejar que sea la entrada para sus pruebas? Si está utilizando la implementación, también está probando eso, convirtiendo su prueba en una de integración. – Morten

+0

Cierto, no probaría contra el ThirdPartyClassWrapper. Sería un trozo de la interfaz. Sin embargo, no puedo colgar una clase estática. Dejando a un lado las pruebas, creo que realmente se beneficiaría más adelante en el futuro. –

5

encontrado una manera alrededor de ella para las clases no selladas.

1 - heredan de la clase externa

class MyWrapper : ExternalClass 

2 - Extracto de interfaz para todos los métodos públicos

class MyWrapper : ExternalClass, IExternalClass 

3 - Retirar la herencia de la clase externa

class MyWrapper : IExternalClass 

4 - Obtendrá una pista sobre el nombre de la clase sobre los miembros de la interfaz que no se implementa.Alt + Enter en él y dejar que ReSharper implementar automáticamente

5 - Utilice esta plantilla de código para envolver propiedades

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

6 - Utilice esta plantilla de código para envolver métodos

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

Otra muy resbaladizo La forma de hacer esto es usar Resharper para generar los "Miembros delegados" para usted como se describe aquí: https://stackoverflow.com/a/2150827/1703887

Pasos:

  1. crear una nueva clase que hereda de la clase que desea envolver con una variable privada de esa clase de tipo:

    public class ThirdPartyClassWrapper : ThirdPartyClass 
    { 
        private ThirdPartyClass _ThirdPartyClass; 
    } 
    
  2. Hacer un Alt-Insert en/sobre la clase de usar Resharper para generar "Delegación de miembros". Elija los métodos que desea exponer y pasar a la variable privada.

  3. Si tiene instalada la versión gratuita del GhostDoc extension, puede resaltar todas las propiedades, métodos, etc. creados y hacer una Ctrl-D para tomar automáticamente toda la documentación de la clase base y ponerla en el nuevos miembros. (Resharper puede hacer esto también, pero creo que tendrías que poner "nuevo" en cada elemento que luego te permitiría ingresar Alt y seleccionar "Agregar comentarios xml-doc" desde el menú emergente Resharper).

  4. Puede eliminar la clase base y realizar una limpieza adicional en caso de que las firmas de método/propiedad expongan cualquier otro tipo que deba envolver.

0

Le sugiero que mire en un marco de burla como Fakeiteasy.

Pero para darle exactamente lo que pidió ver a continuación. Sospecho que ReSharper no tuvo esta operación cuando otros respondieron.

  1. añadir la interfaz de la clase que desea ser la clase de embalaje

    class MyWebElement : IWebElement { } 
    

  1. Buscar/Haga clic en "aplicación Delegado de" YourInterfaceHere "a un nuevo campo Delegate Implementation

  1. seleccionadas las opciones de Delegate options

  1. Haga clic en finalizar y disfrutar de su nueva clase

    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; } 
        } 
    } 
    
Cuestiones relacionadas