rompiendo dependencias contenidas en ensamblados .net mediante la refactorización de su código...
TRANSCRIPT
![Page 1: Rompiendo dependencias contenidas en ensamblados .NET mediante la refactorización de su código Intermedio](https://reader036.vdocuments.co/reader036/viewer/2022062406/558e4a2f1a28ab5c518b47ab/html5/thumbnails/1.jpg)
Herramienta para romper dependencias en ensamblados .NET
mediante la refactorización de su código intermedio.
Presentado por:Jair Cazarin Villanueva
Bajo la supervisión de:Dr. Mauricio Osorio.
Dr. Mircea Trofin.
Universidad de las Américas, Puebla
![Page 2: Rompiendo dependencias contenidas en ensamblados .NET mediante la refactorización de su código Intermedio](https://reader036.vdocuments.co/reader036/viewer/2022062406/558e4a2f1a28ab5c518b47ab/html5/thumbnails/2.jpg)
Agenda.
• Contexto del Problema.– Programación Orientada a Objetos.– Dependencias.
• Objetivos.• Alcances y Limitaciones.• Análisis del Problema.• Diseño e Implementación.• Resultado y Pruebas.• Conclusiones.
![Page 3: Rompiendo dependencias contenidas en ensamblados .NET mediante la refactorización de su código Intermedio](https://reader036.vdocuments.co/reader036/viewer/2022062406/558e4a2f1a28ab5c518b47ab/html5/thumbnails/3.jpg)
Programación Orientada a Objetos
![Page 4: Rompiendo dependencias contenidas en ensamblados .NET mediante la refactorización de su código Intermedio](https://reader036.vdocuments.co/reader036/viewer/2022062406/558e4a2f1a28ab5c518b47ab/html5/thumbnails/4.jpg)
“El paradigma de la programación orientada a objetos, también conocida como POO, es la que usa objetos y sus interacciones para diseñar aplicaciones.”
![Page 5: Rompiendo dependencias contenidas en ensamblados .NET mediante la refactorización de su código Intermedio](https://reader036.vdocuments.co/reader036/viewer/2022062406/558e4a2f1a28ab5c518b47ab/html5/thumbnails/5.jpg)
![Page 6: Rompiendo dependencias contenidas en ensamblados .NET mediante la refactorización de su código Intermedio](https://reader036.vdocuments.co/reader036/viewer/2022062406/558e4a2f1a28ab5c518b47ab/html5/thumbnails/6.jpg)
Características Principales
![Page 7: Rompiendo dependencias contenidas en ensamblados .NET mediante la refactorización de su código Intermedio](https://reader036.vdocuments.co/reader036/viewer/2022062406/558e4a2f1a28ab5c518b47ab/html5/thumbnails/7.jpg)
![Page 8: Rompiendo dependencias contenidas en ensamblados .NET mediante la refactorización de su código Intermedio](https://reader036.vdocuments.co/reader036/viewer/2022062406/558e4a2f1a28ab5c518b47ab/html5/thumbnails/8.jpg)
![Page 9: Rompiendo dependencias contenidas en ensamblados .NET mediante la refactorización de su código Intermedio](https://reader036.vdocuments.co/reader036/viewer/2022062406/558e4a2f1a28ab5c518b47ab/html5/thumbnails/9.jpg)
Flexible
![Page 10: Rompiendo dependencias contenidas en ensamblados .NET mediante la refactorización de su código Intermedio](https://reader036.vdocuments.co/reader036/viewer/2022062406/558e4a2f1a28ab5c518b47ab/html5/thumbnails/10.jpg)
Fácil de mantener.
![Page 11: Rompiendo dependencias contenidas en ensamblados .NET mediante la refactorización de su código Intermedio](https://reader036.vdocuments.co/reader036/viewer/2022062406/558e4a2f1a28ab5c518b47ab/html5/thumbnails/11.jpg)
![Page 12: Rompiendo dependencias contenidas en ensamblados .NET mediante la refactorización de su código Intermedio](https://reader036.vdocuments.co/reader036/viewer/2022062406/558e4a2f1a28ab5c518b47ab/html5/thumbnails/12.jpg)
Dependencias.
![Page 13: Rompiendo dependencias contenidas en ensamblados .NET mediante la refactorización de su código Intermedio](https://reader036.vdocuments.co/reader036/viewer/2022062406/558e4a2f1a28ab5c518b47ab/html5/thumbnails/13.jpg)
Tipos de dependencias.
![Page 14: Rompiendo dependencias contenidas en ensamblados .NET mediante la refactorización de su código Intermedio](https://reader036.vdocuments.co/reader036/viewer/2022062406/558e4a2f1a28ab5c518b47ab/html5/thumbnails/14.jpg)
Solución: Refactorizar.
“Refactorizar es el proceso de cambiar un software de tal forma que el comportamiento externo no cambia, más bien, se mejora su estructura interna.”
![Page 15: Rompiendo dependencias contenidas en ensamblados .NET mediante la refactorización de su código Intermedio](https://reader036.vdocuments.co/reader036/viewer/2022062406/558e4a2f1a28ab5c518b47ab/html5/thumbnails/15.jpg)
• Desafortunadamente, la refactorización es un proceso que se aplica cuando se tiene acceso al código fuente.
• Ignorando las veces cuando:
![Page 16: Rompiendo dependencias contenidas en ensamblados .NET mediante la refactorización de su código Intermedio](https://reader036.vdocuments.co/reader036/viewer/2022062406/558e4a2f1a28ab5c518b47ab/html5/thumbnails/16.jpg)
Objetivo General.
• Investigar la refactorización de ensamblados binarios con el objetivo de mejorar la reusabilidad y capacidad de resolución de frameworks
![Page 17: Rompiendo dependencias contenidas en ensamblados .NET mediante la refactorización de su código Intermedio](https://reader036.vdocuments.co/reader036/viewer/2022062406/558e4a2f1a28ab5c518b47ab/html5/thumbnails/17.jpg)
Objetivo General.
• Para lograr lo anterior, se desarrolló una herramienta que refactoriza ensamblados existentes, con el objetivo de romper las dependencias contenidas entre distintas clases, y de esta forma hacer posible satisfacer estas dependencias con otros tipos, mediante la mejora de la modularización y extensibilidad de los componentes.
![Page 18: Rompiendo dependencias contenidas en ensamblados .NET mediante la refactorización de su código Intermedio](https://reader036.vdocuments.co/reader036/viewer/2022062406/558e4a2f1a28ab5c518b47ab/html5/thumbnails/18.jpg)
Afterex = Extensibility after-the-fact.
![Page 19: Rompiendo dependencias contenidas en ensamblados .NET mediante la refactorización de su código Intermedio](https://reader036.vdocuments.co/reader036/viewer/2022062406/558e4a2f1a28ab5c518b47ab/html5/thumbnails/19.jpg)
Alcances y Limitaciones.
• .NET Framework y ensamblados .NET.• Dependencias contenidas y directas.• Solución completa para el escenario de
dependencias contenidas.• En el caso de las dependencias directas solo se
abordó el tema y se hicieron los primeros experimentos con los casos de parámetros.
• Aplicación basada en consola.
![Page 20: Rompiendo dependencias contenidas en ensamblados .NET mediante la refactorización de su código Intermedio](https://reader036.vdocuments.co/reader036/viewer/2022062406/558e4a2f1a28ab5c518b47ab/html5/thumbnails/20.jpg)
Análisis del problema.
• Metodología ágil.• Definición de enfoques y tecnologías a usar.
![Page 21: Rompiendo dependencias contenidas en ensamblados .NET mediante la refactorización de su código Intermedio](https://reader036.vdocuments.co/reader036/viewer/2022062406/558e4a2f1a28ab5c518b47ab/html5/thumbnails/21.jpg)
Dependencia Contenida.
• Si tenemos un DLL D con una clase d, y un DLL C con una clase c, una dependencia contenida de D a C, sería si encontráramos instrucciones como al siguiente en clases de d:
• c someVariable = new c(…Parameters…);• ic someVariable = new c(…Parameters…);
![Page 22: Rompiendo dependencias contenidas en ensamblados .NET mediante la refactorización de su código Intermedio](https://reader036.vdocuments.co/reader036/viewer/2022062406/558e4a2f1a28ab5c518b47ab/html5/thumbnails/22.jpg)
Dependencia Directa.
• C someMethod(…);• SomeType someOtherMethod(…,C parameter,
…);• C.someStaticMember(…);• class Cls:C (<-if C wasn’t sealed)• class Cls:SomeGeneric<C>
![Page 23: Rompiendo dependencias contenidas en ensamblados .NET mediante la refactorización de su código Intermedio](https://reader036.vdocuments.co/reader036/viewer/2022062406/558e4a2f1a28ab5c518b47ab/html5/thumbnails/23.jpg)
.NET Framework.
![Page 24: Rompiendo dependencias contenidas en ensamblados .NET mediante la refactorización de su código Intermedio](https://reader036.vdocuments.co/reader036/viewer/2022062406/558e4a2f1a28ab5c518b47ab/html5/thumbnails/24.jpg)
CLR
![Page 25: Rompiendo dependencias contenidas en ensamblados .NET mediante la refactorización de su código Intermedio](https://reader036.vdocuments.co/reader036/viewer/2022062406/558e4a2f1a28ab5c518b47ab/html5/thumbnails/25.jpg)
Ejecución de código administrado.
![Page 26: Rompiendo dependencias contenidas en ensamblados .NET mediante la refactorización de su código Intermedio](https://reader036.vdocuments.co/reader036/viewer/2022062406/558e4a2f1a28ab5c518b47ab/html5/thumbnails/26.jpg)
CIL.
.method static void main(){ .entrypoint .maxstack 1 ldstr "Hello world!" call void [mscorlib]System.Console::WriteLine(string) ret}
![Page 27: Rompiendo dependencias contenidas en ensamblados .NET mediante la refactorización de su código Intermedio](https://reader036.vdocuments.co/reader036/viewer/2022062406/558e4a2f1a28ab5c518b47ab/html5/thumbnails/27.jpg)
Ensamblados.
![Page 28: Rompiendo dependencias contenidas en ensamblados .NET mediante la refactorización de su código Intermedio](https://reader036.vdocuments.co/reader036/viewer/2022062406/558e4a2f1a28ab5c518b47ab/html5/thumbnails/28.jpg)
CECIL.
![Page 29: Rompiendo dependencias contenidas en ensamblados .NET mediante la refactorización de su código Intermedio](https://reader036.vdocuments.co/reader036/viewer/2022062406/558e4a2f1a28ab5c518b47ab/html5/thumbnails/29.jpg)
Dependency Injection.
• Dependency Injection es un patrón de diseño de objetos en los cuales estos son colocados por entidades externas.
• No se usa el operador new para construir objetos.
• Una forma de implementarlo es usando factories.• Esto nos da la flexibilidad de crear
implementaciones alternas especificándola usando un archivo de configuración.
![Page 30: Rompiendo dependencias contenidas en ensamblados .NET mediante la refactorización de su código Intermedio](https://reader036.vdocuments.co/reader036/viewer/2022062406/558e4a2f1a28ab5c518b47ab/html5/thumbnails/30.jpg)
Implementación
![Page 31: Rompiendo dependencias contenidas en ensamblados .NET mediante la refactorización de su código Intermedio](https://reader036.vdocuments.co/reader036/viewer/2022062406/558e4a2f1a28ab5c518b47ab/html5/thumbnails/31.jpg)
Capa de Framework.
![Page 32: Rompiendo dependencias contenidas en ensamblados .NET mediante la refactorización de su código Intermedio](https://reader036.vdocuments.co/reader036/viewer/2022062406/558e4a2f1a28ab5c518b47ab/html5/thumbnails/32.jpg)
Capa de Framework.
• El framework fue desarrollado siguiendo las mejores prácticas dictadas por el Framework Design Guidelines.
![Page 33: Rompiendo dependencias contenidas en ensamblados .NET mediante la refactorización de su código Intermedio](https://reader036.vdocuments.co/reader036/viewer/2022062406/558e4a2f1a28ab5c518b47ab/html5/thumbnails/33.jpg)
Capa de implementación.
![Page 34: Rompiendo dependencias contenidas en ensamblados .NET mediante la refactorización de su código Intermedio](https://reader036.vdocuments.co/reader036/viewer/2022062406/558e4a2f1a28ab5c518b47ab/html5/thumbnails/34.jpg)
Dependency Injection Container.
![Page 35: Rompiendo dependencias contenidas en ensamblados .NET mediante la refactorización de su código Intermedio](https://reader036.vdocuments.co/reader036/viewer/2022062406/558e4a2f1a28ab5c518b47ab/html5/thumbnails/35.jpg)
Rompiendo dependencias contenidas.
Tipo abstracto.
public Interface ISort{ void Sort(int[] list();}
![Page 36: Rompiendo dependencias contenidas en ensamblados .NET mediante la refactorización de su código Intermedio](https://reader036.vdocuments.co/reader036/viewer/2022062406/558e4a2f1a28ab5c518b47ab/html5/thumbnails/36.jpg)
Rompiendo dependencias contenidas.
Implementación concreta.
public class BubbleSort : ISort{ public void Sort(int[] list) { …
Implementation goes here…}}
![Page 37: Rompiendo dependencias contenidas en ensamblados .NET mediante la refactorización de su código Intermedio](https://reader036.vdocuments.co/reader036/viewer/2022062406/558e4a2f1a28ab5c518b47ab/html5/thumbnails/37.jpg)
Rompiendo dependencias contenidas.
Tipo dependendiente.
public class DependentType { void m1() { ISort sorter = new BubbleSort(); … sorter.Sort(numbers) …. }}
![Page 38: Rompiendo dependencias contenidas en ensamblados .NET mediante la refactorización de su código Intermedio](https://reader036.vdocuments.co/reader036/viewer/2022062406/558e4a2f1a28ab5c518b47ab/html5/thumbnails/38.jpg)
• Propiedad
private static Func<ISort> sortBaseTypeFactory = null;
![Page 39: Rompiendo dependencias contenidas en ensamblados .NET mediante la refactorización de su código Intermedio](https://reader036.vdocuments.co/reader036/viewer/2022062406/558e4a2f1a28ab5c518b47ab/html5/thumbnails/39.jpg)
Implementación del Factorypublic static Func<ISort> SortBaseTypeFactory{ get { if (null == SortBaseTypeFactory) { SettingsReader settingsReader = new SettingsReader(); string assemblyName = settingsReader.GetValue("Assembly"); string typeName = settingsReader.GetValue("Type"); string methodName = settingsReader.GetValue("Method"); string assemblyFullName =Path.Combine(Directory.GetCurrentDirectory(), assemblyName); MethodInfo method =
Assembly.LoadFile(assemblyFullName).GetType(typeName).GetMethod(methodName); sortBaseTypeFactory = () => (String)(method.Invoke(null, null)); } return baseTypeFactory; } set { sortBaseTypeFactory = value; }}
![Page 40: Rompiendo dependencias contenidas en ensamblados .NET mediante la refactorización de su código Intermedio](https://reader036.vdocuments.co/reader036/viewer/2022062406/558e4a2f1a28ab5c518b47ab/html5/thumbnails/40.jpg)
Factory Method:
public static ISort GetBubbleSortInstance()
{ return new BubbleSort();}
![Page 41: Rompiendo dependencias contenidas en ensamblados .NET mediante la refactorización de su código Intermedio](https://reader036.vdocuments.co/reader036/viewer/2022062406/558e4a2f1a28ab5c518b47ab/html5/thumbnails/41.jpg)
XML de configuración.
<Settings> <Assembly>SortFactory.dll</Assembly>
<Type>SortFactory.Factory</Type><Method>SomeMethod</Method></Settings>
![Page 42: Rompiendo dependencias contenidas en ensamblados .NET mediante la refactorización de su código Intermedio](https://reader036.vdocuments.co/reader036/viewer/2022062406/558e4a2f1a28ab5c518b47ab/html5/thumbnails/42.jpg)
Ahora instanciamos así:
ISort sorter = Factory.SortBaseTypeFactory();
En lugar de:
ISort sorter = new BubbleSort();
![Page 43: Rompiendo dependencias contenidas en ensamblados .NET mediante la refactorización de su código Intermedio](https://reader036.vdocuments.co/reader036/viewer/2022062406/558e4a2f1a28ab5c518b47ab/html5/thumbnails/43.jpg)
Nuevo componente.
public class QuickSort : ISort{ public void Sort(int[] list) { …Implementation goes here… }}
![Page 44: Rompiendo dependencias contenidas en ensamblados .NET mediante la refactorización de su código Intermedio](https://reader036.vdocuments.co/reader036/viewer/2022062406/558e4a2f1a28ab5c518b47ab/html5/thumbnails/44.jpg)
Factory Method
public static ISort GetQuickSortInstance(){ return new QuickSort();}
![Page 45: Rompiendo dependencias contenidas en ensamblados .NET mediante la refactorización de su código Intermedio](https://reader036.vdocuments.co/reader036/viewer/2022062406/558e4a2f1a28ab5c518b47ab/html5/thumbnails/45.jpg)
XML de configuración.
<Settings> <Assembly>newComponent.dll</Assembly>
<Type>QuickSortComponent</Type><Method>GetQuickSortInstance</Method></Settings>
![Page 46: Rompiendo dependencias contenidas en ensamblados .NET mediante la refactorización de su código Intermedio](https://reader036.vdocuments.co/reader036/viewer/2022062406/558e4a2f1a28ab5c518b47ab/html5/thumbnails/46.jpg)
Refactorizando instanciaciones.RefactorInstantiations(baseType, concreteType, targetAssembly)1 Foreach Type t in targetAssembly.Types2 Foreach Method m in t.Methods3 If method doesn’t has a body4 Continue5 If method doesn’t contain a variable of type6 baseType7 Continue8 Foreach Instruction i in m.Body9 If perform a new instantiation of10 concreteType11 Replace the instruction to call12 the property instead of new.
![Page 47: Rompiendo dependencias contenidas en ensamblados .NET mediante la refactorización de su código Intermedio](https://reader036.vdocuments.co/reader036/viewer/2022062406/558e4a2f1a28ab5c518b47ab/html5/thumbnails/47.jpg)
public class DependentType { void m1() { BubbleSort sorter = new
BubbleSort(); … sorter.Sort(numbers) …. }}
![Page 48: Rompiendo dependencias contenidas en ensamblados .NET mediante la refactorización de su código Intermedio](https://reader036.vdocuments.co/reader036/viewer/2022062406/558e4a2f1a28ab5c518b47ab/html5/thumbnails/48.jpg)
Refactorizando instanciaciones concretas.
RefactorInstantiations(concreteType, targetAssembly)1 newInterface ← new Interface2 Declare the operations of concreteType in
newInterface3 Change concreteType to implemente newInterface4 Perform RefactorConcreteImplementations5 the property instead of new
AND6 change the variable to be
baseType.
![Page 49: Rompiendo dependencias contenidas en ensamblados .NET mediante la refactorización de su código Intermedio](https://reader036.vdocuments.co/reader036/viewer/2022062406/558e4a2f1a28ab5c518b47ab/html5/thumbnails/49.jpg)
Dependencias Directas.
• Se logró crear una capa más abstracta para el API que define.
• Sin embargo, aún no sabemos cómo romper la dependencia completamente.
• Tampoco sabemos cómo desarrolladores terceros puedan utilizar esta capa más abstracta o tomar ventaja de ella.
![Page 50: Rompiendo dependencias contenidas en ensamblados .NET mediante la refactorización de su código Intermedio](https://reader036.vdocuments.co/reader036/viewer/2022062406/558e4a2f1a28ab5c518b47ab/html5/thumbnails/50.jpg)
Refactorizando Parámetros.RefactorParameters(baseType, concreteType, targetAssembly)1 Foreach Type t in target.AssemblyTypes2 Foreach Method m in t.Methods3 If m contain parameter of type concreteType4 Change the parameter to be baseType6 mbody ← m.MethodBody5 Make the method protected and abstract.6 Make the type to be abstract.7 Create a new type tAbstract8 Create a new assemblyAbstract9 Make tAbstract inherits from t10 Implement abstract methods of t with
mbody.11 Add tAbstract to assemblyAbstract
![Page 51: Rompiendo dependencias contenidas en ensamblados .NET mediante la refactorización de su código Intermedio](https://reader036.vdocuments.co/reader036/viewer/2022062406/558e4a2f1a28ab5c518b47ab/html5/thumbnails/51.jpg)
Renombramiento.
AssemblyRenameApproach(originalAssembly, newAssembly, originalType, Type newType)
1 oname ← originalAssembly.Name2 originalAssembly.name ← newAssembly.Name3 newAssembly.name ← oname4 otype ← originalType.name5 originalType ← newType.Name6 newType ← otype
![Page 52: Rompiendo dependencias contenidas en ensamblados .NET mediante la refactorización de su código Intermedio](https://reader036.vdocuments.co/reader036/viewer/2022062406/558e4a2f1a28ab5c518b47ab/html5/thumbnails/52.jpg)
Refactorizando Parámetros de retorno.
RefactorReturnParameters(baseType, concreteType, targetAssembly)
1 Foreach Type t in target.AssemblyTypes2 Foreach Method m in t.Methods3 If return type of m is of type concreteType4 Find which methods calls m5 Move m to the new assembly and
type.6 If the list of method that calls m > 17 Move all methods to the new
assembly8 Update calls to m.
![Page 53: Rompiendo dependencias contenidas en ensamblados .NET mediante la refactorización de su código Intermedio](https://reader036.vdocuments.co/reader036/viewer/2022062406/558e4a2f1a28ab5c518b47ab/html5/thumbnails/53.jpg)
Capa de aplicación.
![Page 54: Rompiendo dependencias contenidas en ensamblados .NET mediante la refactorización de su código Intermedio](https://reader036.vdocuments.co/reader036/viewer/2022062406/558e4a2f1a28ab5c518b47ab/html5/thumbnails/54.jpg)
Capa de aplicación.
• Extensible. Se pueden cargar nuevas reglas de refactorización.
• Fácil de cambiar a otra implementación. Ejemplo: Una interfaz gráfica.
• Genera un archivo XML con un resumen de las reglas aplicadas.
![Page 55: Rompiendo dependencias contenidas en ensamblados .NET mediante la refactorización de su código Intermedio](https://reader036.vdocuments.co/reader036/viewer/2022062406/558e4a2f1a28ab5c518b47ab/html5/thumbnails/55.jpg)
Pruebas y Resultados.
![Page 56: Rompiendo dependencias contenidas en ensamblados .NET mediante la refactorización de su código Intermedio](https://reader036.vdocuments.co/reader036/viewer/2022062406/558e4a2f1a28ab5c518b47ab/html5/thumbnails/56.jpg)
Escenario 2.
![Page 57: Rompiendo dependencias contenidas en ensamblados .NET mediante la refactorización de su código Intermedio](https://reader036.vdocuments.co/reader036/viewer/2022062406/558e4a2f1a28ab5c518b47ab/html5/thumbnails/57.jpg)
Resumiendo
• La aplicación ya no es responsable de encontrar sus dependencias.
• El contenedor se encarga de encontrar esas dependencias.
• Añadimos flexibilidad a la aplicación para futuros cambios.
• Promovimos la disminución del acoplamiento entre componentes, por lo cual facilitamos las pruebas de unidad.
![Page 58: Rompiendo dependencias contenidas en ensamblados .NET mediante la refactorización de su código Intermedio](https://reader036.vdocuments.co/reader036/viewer/2022062406/558e4a2f1a28ab5c518b47ab/html5/thumbnails/58.jpg)
Conclusiones.
![Page 59: Rompiendo dependencias contenidas en ensamblados .NET mediante la refactorización de su código Intermedio](https://reader036.vdocuments.co/reader036/viewer/2022062406/558e4a2f1a28ab5c518b47ab/html5/thumbnails/59.jpg)
Trabajo a Futuro.
• Terminar un escenario completo de las dependencias directas.
• Estudiar las dependencias indirectas y ocultas.• Crear un contenedor de dependencias para
aplicaciones existentes más robusto.• Mejorar la complejidad de los algoritmos.• Extender el API y fusionarlo con CECIL.
![Page 60: Rompiendo dependencias contenidas en ensamblados .NET mediante la refactorización de su código Intermedio](https://reader036.vdocuments.co/reader036/viewer/2022062406/558e4a2f1a28ab5c518b47ab/html5/thumbnails/60.jpg)
?