2011-08-31 26 views
8

Esto debería ser simple, pero no puedo encontrar nada por ahí.Generación automática de una clase Wrapper en C# usando Composición

tengo una clase en una asamblea (una biblioteca compartida - es un conjunto de clases de proxy para un servicio Web) que tienen una clase de otro montaje (proyecto web)

hay una clase llamada " Perfil "que está en el conjunto de Proxy. Hay un conjunto de clases que "usan" un Perfil en el proyecto web. Cuando no hay ningún usuario conectado, se usa un GenericProfile.

Siguiendo el principio de "separación de preocupaciones" .... El ensamblaje Proxy lo utilizan otros proyectos y solo se ocupa del servicio web. El proyecto web solo tiene elementos web allí

Sin embargo, ahora existe la necesidad de un "Perfil genérico", piénselo como "Usuario invitado".

Lo lógico es crear una interfaz llamada IProfile y hacer que ambas clases se deriven de ella. Pero eso crearía una dependencia circular entre los dos ensamblajes.

La siguiente mejor idea es crear una tercera asamblea llamada MyInterfaces y poner el IProfile allí, pero eso causa una violación del principio de separación de preocupaciones en mi opinión. Por lo menos, una instancia de este problema parece una razón demasiado pequeña para hacer un módulo extra en mi solución.

Introduzca la clase contenedora - o la clase contenedora Compuesto (lo que quieras llamarlo)

Busco algo que acaba por generar algo como esto más adelante. ¿Hay alguna herramienta o extensión de Visual Studio que lo haga? Tal vez un archivo .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; } } 
    } 

} 
+1

Y parece que alguien le preguntó algo similar a esto ... http://stackoverflow.com/ques ciones/2150416/generate-pass-through-code-when-preferring-composition-over-inheritance – 010110110101

+0

No tengo ReSharper aunque ... – 010110110101

+1

Usaría T4 para esto (como pensaste también) pero no sé si ya existe una plantilla completa para esto. Pero creo que una plantilla así podría escribirse con bastante facilidad utilizando la reflexión. –

Respuesta

0

Si me enfrentaba a su problema original, que había puesto IProfile en la biblioteca compartida, junto con la clase Profile. Su proyecto web puede implementar la clase GenericProfile que necesita, nada más necesita saber al respecto, y otros clientes de la biblioteca pueden hacer lo mismo según sea necesario. También sería útil para probar la biblioteca.

2

No entiendo completamente lo que está tratando de lograr, pero a continuación es cómo generaría una clase contenedora con ReSharper.

Personalmente, si mi empleador no quiere pagar ReSharper, lo compro. Me hace un mejor desarrollador. Le sugiero que considere adquirirlo como una inversión en su carrera. Anti-Descargo de responsabilidad: no estoy en absoluto conectado o patrocinado por ReSharper.

  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