Installing NuGet Packages using C#
We’ve been creating a system where we need to download and use NuGet packages dynamically, runtime. To handle this, we use NuGet.Core.
Using NuGet.Core
NuGet.Core contains the basic functionality for installing, removing and updating packages. The main classes when dealing with NuGet.Core are PackageRepositoryFactoryand PackageManager. PackageRepositoryFactory creates the “connection” into your NuGet repository and PackageManager is used to install the packages. Here’s an example code which covers the following situation:
- We have a console app
- We use local NuGet repository (file system)
var repo = PackageRepositoryFactory.Default.CreateRepository("file://C:/temp/packages"); var packageManager = new PackageManager(repo, _installLocation); var package = repo.FindPackage("mypackage", SemanticVersion.Parse("1.0.0.0")); packageManager.PackageInstalled += (sender, eventArgs) => { var fileRoot = System.IO.Path.GetDirectoryName(Path.Combine(eventArgs.InstallPath, eventArgs.Package.AssemblyReferences.First().Path)); Console.WriteLine(fileRoot); }; packageManager.InstallPackage(package, false, true, true);
PackageManager’s even PackageInstalled usually causes some grief because it is raised only when package is actually installed: If it’s already installed, PackageInstalled-event is skipped.
Using classes from NuGet runtime
We use MEF to actually execute the code inside the NuGet packages:
- Make sure that the packages contains classes which implement known interfaces.
- Use DirectoryCatalog to initialize the MEF container.
- Use GetExportedValues to get the implementing classes.
For example:
packageManager.PackageInstalled += (sender, eventArgs) => { var fileRoot = System.IO.Path.GetDirectoryName(Path.Combine(eventArgs.InstallPath, eventArgs.Package.AssemblyReferences.First().Path)); if (fileRoot == null) return; var catalog = new AggregateCatalog( new DirectoryCatalog(fileRoot, "*.dll")); var container = new CompositionContainer(catalog); var activities = container.GetExportedValues<IActivity>(); foreach (var activity in activities) { activity.Run(); } };