Estoy buscando una forma de ejecutar el código ejecutando los siguientes pasos:
Por ahora estoy luchando con el tercer paso. No puedo averiguar cómo cargar mi paquete en tiempo de ejecución.
Mi pregunta principal son:
Ejemplo de código n.º 1:
private static void getPackageByNameAndVersion(string packageID, string version) { IPackageRepository repo = PackageRepositoryFactory.Default .CreateRepository("https://packages.nuget.org/api/v2"); string path = "C:/tmp_repo"; PackageManager packageManager = new PackageManager(repo, path); Console.WriteLine("before dl pkg"); packageManager.InstallPackage(packageID, SemanticVersion.Parse(version)); }Ejemplo de código n.º 2:
private static void loadByAssemblyNameAndTypeName(string assemblyName, string typeName) { AppDomain isolationAppDomain = AppDomain.CreateDomain("tmp"); object a = isolationAppDomain.CreateInstanceAndUnwrap(assemblyName, typeName); Type x = a.GetType(); MethodInfo m = x.GetMethod("Main"); m.Invoke(a, new object[] { }); } Nuget.Core (paquete nuget) es una buena opción, y aquí hay un fragmento de código que tengo que debería poder descargar un paquete nuget por id y version
var repo = PackageRepositoryFactory.Default .CreateRepository("https://packages.nuget.org/api/v2"); string path = "c:\\temp"; var packageManager = new PackageManager(repo, path); packageManager.PackageInstalled += PackageManager_PackageInstalled; var package = repo.FindPackage("packageName", SemanticVersion.Parse("1.0.0")); if (package != null) { packageManager.InstallPackage(package, false, true); }Observe que conecté un controlador de eventos al evento
PackageInstalledde la clasePackageManager.
Dado que la API de reflexión no proporciona una forma de cargar un ensamblaje en un dominio específico, crearemos una clase de proxy que actúe como un cargador en nuestro dominio aislado:
public class TypeProxy : MarshalByRefObject { public Type LoadFromAssembly(string assemblyPath, string typeName) { try { var asm = Assembly.LoadFile(assemblyPath); return asm.GetType(typeName); } catch (Exception) { return null; } } }Aquí viene la parte compleja:
private static void PackageManager_PackageInstalled(object sender, PackageOperationEventArgs e) { var files = e.FileSystem.GetFiles(e.InstallPath, "*.dll", true); foreach (var file in files) { try { AppDomain domain = AppDomain.CreateDomain("tmp"); Type typeProxyType = typeof(TypeProxy); var typeProxyInstance = (TypeProxy)domain.CreateInstanceAndUnwrap( typeProxyType.Assembly.FullName, typeProxyType.FullName); var type = typeProxyInstance.LoadFromAssembly(file, "<KnownTypeName>"); object instance = domain.CreateInstanceAndUnwrap(type.Assembly.FullName, type.FullName); } catch (Exception ex) { Console.WriteLine("failed to load {0}", file); Console.WriteLine(ex.ToString()); } } }Tenga en cuenta que este método es el controlador de eventos que se ejecuta después de descargar el paquete nuget
También
Tenga en cuenta que deberá reemplazar
<KnownTypeName>con el nombre de tipo esperado que proviene del ensamblado (o tal vez ejecutar un descubrimiento de todos los tipos públicos en el ensamblado)
Vale la pena señalar que no he ejecutado este código yo mismo y no puedo garantizar que funcione de inmediato, y aún podría necesitar algunos ajustes. pero esperemos que sea el concepto el que te permita solucionar el problema.
¡No hagas eso! Probablemente esté intentando cargar contenido de NuGet en la computadora de un cliente para ahorrar espacio en la distribución de su software. ¿No es eso?
El enfoque recomendado común es descargar el contenido de NuGet como segundo paso de una compilación automatizada (después de descargar el código fuente), compilar el software y ejecutar las pruebas automatizadas con el contenido de NuGet que ha descargado. Y luego distribuya la compilación con el contenido de NuGet que probó como la unidad completa compleja.