My problem is I am invoking a 3rd party method asynchronously and it can sometimes hang or often take a long time to complete but we need to kill it for whatever reason.
Since it's third party, tasks and cancellation tokens can't be used to
cancel the computation.
From what I read Thread.Abort() is evil. Especially since this method will be reading and writing files and making connections to our database
From what I've seen AppDomain is something I could have used, but this isn't available in .netcore
It seems the only way to execute this method in a way I can kill immediately and safely is to run it in a process and kill that process. But even this I'm not sure is possible. It seems only .exe can be ran by a process.
Any help is greatly appreciated.
There is a solution for AppDomain in .net core, it is explained in this article.
long story short:
In order to replace AppDomain Unload event use:
System.Runtime.Loader.AssemblyLoadContext.Default.Unloading += context => InvokeBatchProcessors();
this is a part of System.Runtime.Loader library.
Appdomain GetAssemblies:
public static IEnumerable<Assembly> GetReferencingAssemblies(string assemblyName)
{
var assemblies = new List<Assembly>();
var dependencies = DependencyContext.Default.RuntimeLibraries;
foreach (var library in dependencies)
{
if (IsCandidateLibrary(library, assemblyName))
{
var assembly = Assembly.Load(new AssemblyName(library.Name));
assemblies.Add(assembly);
}
}
return assemblies;
}
private static bool IsCandidateLibrary(RuntimeLibrary library, assemblyName)
{
return library.Name == (assemblyName)
|| library.Dependencies.Any(d => d.Name.StartsWith(assemblyName));
}
This is part of Microsoft.Extensions.DependencyModel package.
Creating a Pollyfill for AppDomain.CurrentDomain.GetAssemblies:
public class AppDomain
{
public static AppDomain CurrentDomain { get; private set; }
static AppDomain()
{
CurrentDomain = new AppDomain();
}
public Assembly[] GetAssemblies()
{
var assemblies = new List<Assembly>();
var dependencies = DependencyContext.Default.RuntimeLibraries;
foreach (var library in dependencies)
{
if (IsCandidateCompilationLibrary(library))
{
var assembly = Assembly.Load(new AssemblyName(library.Name));
assemblies.Add(assembly);
}
}
return assemblies.ToArray();
}
private static bool IsCandidateCompilationLibrary(RuntimeLibrary compilationLibrary)
{
return compilationLibrary.Name == ("Specify")
|| compilationLibrary.Dependencies.Any(d => d.Name.StartsWith("Specify"));
}
}
Note that these are all examples on how to use AppDomain in .net core, for any how needs to use the functionality of AppDomain in .net core.
Related
I'm trying to develop an extensible application with Blazor WASM, which downloads plugins from server, and caches them at browser storage.
Both downloading and caching APIs are async.
The following AssemblyLoadContext, is responsible to load plugin assemblies.
As plugins may contain multiple assembly files, and as the project should support lazy loading of referenced assemblies, I'm handling the Resolving event as follow:
public class PluginAssemblyLoadContext : AssemblyLoadContext
{
private readonly IPluginResolver? _pluginResolver;
public PluginAssemblyLoadContext(string name) : this(name, null)
{
}
public PluginAssemblyLoadContext(string name, IPluginResolver? pluginResolver) : base(name, isCollectible: true)
{
_pluginResolver = pluginResolver;
if (pluginResolver != null)
{
Resolving += ResolveAssembly;
}
}
protected override Assembly? Load(AssemblyName name)
{
return null;
}
private Assembly? ResolveAssembly(AssemblyLoadContext context, AssemblyName assemblyName)
{
try
{
var assembly = AssemblyLoadContext.Default.Assemblies.FirstOrDefault(x => x.GetName().Name == assemblyName.Name);
if (assembly == null)
{
var task = _pluginResolver?.ResolveAsync(context, assemblyName);
if (task != null)
{
task.Wait(); // <- The problem!
assembly = task.Result; // <- The problem!
}
}
if (assembly == null)
{
// TODO: Log...
}
return assembly;
}
catch (Exception ex)
{
// TODO: Log...
throw;
}
}
}
The problem is that I can't call the async API from this method as it throws an exception telling "Cannot wait on monitors on this runtime." and I couldn't figure out how should I call them synchronously.
Thanks for any help
It seems like you are trying to block the main execution thread by doing.Wait() call. This is bad because the main thread may be responsible for handling UI updates. If it is blocked - the UI of the application will be frozen while your task is in progress. I believe this is the main reason you are getting this error.
The solution I may propose - do not wait till the task is finished. Instead, add a callback to it via .ContinueWith(). In that callback, you may handle the result of the execution and finish your business logic (in your case - perform logging).
Is it possible to rewrite this into async-await? That's to only async way, Blazor Webassambly can handle at the moment.
Or a more dirty way:
Call a js function, that calls back
[JSInvokable] public async Task<Assembly?> GetTaskResult(Task task)
=> await task;
I'm afraid that the AssemblyLoadContext doesn't really leave you with any other option. In ASP.NET Core for example, when you want to write a middleware, you do this:
app.Use((context, next) =>
{
return next();
});
In this case the following overload is called:
Now if you need to do an async call, you can do so:
app.Use(async (context, next) =>
{
await next();
});
But this is only possible because ASP.NET Core provides you with an overload for Use (where the callback parameter is usually of type Func<Task>):
So the bottom line is: AFAIK it's not possible, as long as AssemblyLoadContext doesn't provide events with Task<Assembly> return type.
Your best bet is probably to create an issue on Github.
I am writing a simple plugin and stumbled upon contractType.IsAssignableFrom(pluginType) returning different results depending on the order of loading.
Calling IsAssignableFromon the Plugin returns True as expected.
But if I load the Contract assembly before loading the Plugin, IsAssignableFrom on the Plugin returns False.
I am running Win10 and dotnet4.7 but I doubt that has any relevancy.
Code
[TestMethod]
public void SimplyLoadingPlugin_Succeeds()
{
var plugin = Assembly.LoadFrom(PluginPathFilename);
var res = typeof(Contract).IsAssignableFrom(plugin.GetExportedTypes().Single());
Assert.IsTrue(res); // Succeeds.
}
[TestMethod]
public void LoadingContractAndThenPlugin_Fails()
{
var contract = Assembly.LoadFrom(ContractPathFilename);
var plugin = Assembly.LoadFrom(PluginPathFilename);
var res = typeof(Contract).IsAssignableFrom(plugin.GetExportedTypes().Single());
Assert.IsTrue(res); // Fails.
}
To make it harder to test:
If i run the LoadingContractAndThenPlugin_Fails test by itself is fails. But If i run the tests together it is dependent on order. Running SimplyLoadingPlugin_Succeeds first and LoadingContractAndThenPlugin_Fails last, makes both tests green but running them in the reverse order makes both fail.
So somehow the very loading of Contract before Plugin messes up something for me.
I can se nothing related in the GAC.
Below are all files needed. The paths in the probably have to be updated.
4 project with one file in each. 1 solution.
Contract.cs (a library project)
public abstract class Contract
{
public abstract int Version { get; set; }
}
Plugin.cs (a library project)
public class Plugin : Contract
{
public override int Version { get; set; }
}
Tests.cs (a test project)
[TestClass]
public class Tests
{
private const string PluginPath = #"C:\DATA\Projekt\LoadFromOrder\Plugin\bin\Debug";
private string PluginPathFilename = Path.Combine(PluginPath, "Plugin.dll");
private string ContractPathFilename = Path.Combine(PluginPath, "Contract.dll");
[TestMethod]
public void SimplyLoadingPlugin_Succeeds()
{
var plugin = Assembly.LoadFrom(PluginPathFilename);
var res = typeof(Contract).IsAssignableFrom(plugin.GetExportedTypes().Single());
Assert.IsTrue(res); // Succeeds.
}
[TestMethod]
public void LoadingContractAndThenPlugin_Fails()
{
var contract = Assembly.LoadFrom(ContractPathFilename);
var plugin = Assembly.LoadFrom(PluginPathFilename);
var res = typeof(Contract).IsAssignableFrom(plugin.GetExportedTypes().Single());
Assert.IsTrue(res); // Fails.
}
// BEGIN ---- Update. ----
[TestMethod]
public void LoadingPluginFromTestProject_Succeeds()
{
var contract = Assembly.LoadFrom(
#"C:\DATA\Projekt\LoadFromOrder\TestProject\bin\Debug\Contract.dll");
var plugin = Assembly.LoadFrom(PluginPathFilename);
var res = typeof(Contract.Contract).IsAssignableFrom(plugin.GetExportedTypes().Single());
Assert.IsTrue(res); // Succeeds.
}
// END ---- Update. ----
}
Program.cs (a console project)
class Program
{
static void Main(string[] args)
{
var tests = new Tests();
try
{
System.Console.WriteLine("Press A for Success and B for Fail.");
switch (System.Console.ReadKey(true).Key)
{
case ConsoleKey.A:
tests.SimplyLoadingPlugin_Succeeds();
break;
case ConsoleKey.B:
tests.LoadingContractAndThenPlugin_Fails();
break;
}
System.Console.WriteLine("SUCCESS");
}
catch (Exception exc)
{
System.Console.WriteLine($"FAIL: {exc.Message}");
}
}
}
By loading the Contract using Assembly.LoadFrom you are creating a reference ambiguity. That library is already loaded that is why we can do typeof(Contract) no need to load it again...
My recommendation: use reflection to determine what references you have and only load those that are not already there, here is a sample code snippet:
var dllFiles = Directory.GetFiles(DIR, "*.DLL", SearchOption.AllDirectories);
var plugins = new HashSet<Assembly>();
var references = typeof(Program).Assembly.GetReferencedAssemblies();
foreach (var dllPath in dllFiles)
{
string name = Path.GetFileNameWithoutExtension(dllPath);
if (!references.Any(x => x.Name == name) && !plugins.Any(x => x.GetName().Name == name))
plugins.Add(Assembly.LoadFrom(dllPath));
}
On that sample we get every DLL for a given directory (subdirectories included) the DIR can be a relative path like ..\..\.. and only load those that are not already in the assembly references.
And here is the full solution with two plugin projects:
https://github.com/heldersepu/csharp-proj/tree/master/PluginSystem
As #HelderSepu purported, loading the contract assembly a second time may be the problem.
I'd suggest that you test in a different but easier way. Instead of manually (re)loading the assemblies in the tests, just add references to the assemblies/projects in the test project, and directly reference typeof(Contract) and typeof(Plugin) and check if typeof(Contract).IsAssignableFrom(typeof(Plugin)). Nothing complicated, just add the references to the test project.
You do not need to test whether the assembly is loaded correctly, the CLR will handle that. You need to test whether the plugin assembly contains a Contract definition. Whatever use cases you might have for your architecture, it's not whether assembly loading works that you should be worried about; it is whether the plugin has been implemented correctly.
I'm building a web application, where I would like separate concerns, i.e. having abstractions and implementations in different projects.
To achieve this, I've tried to implement a composition root concept, where all implementation must have an instance of ICompositionRootComposer to register services, types etc.
public interface ICompositionRootComposer
{
void Compose(ICompositionConfigurator configurator);
}
In projects that are referred directly in the build hierarchy, implementations of ICompositionRootComposer are called, and services are registered correct in the underlying IoC container.
The problem arises when I'm trying to register services in a project, where I've set up a post build task that copies the built dll to the web project's debug folder:
cp -R $(TargetDir)"assembly and symbol name"* $(SolutionDir)src/"webproject path"/bin/Debug/netcoreapp1.1
I'm loading the assembly with: (Inspiration: How to load assemblies located in a folder in .net core console app)
internal class AssemblyLoader : AssemblyLoadContext
{
private string folderPath;
internal AssemblyLoader(string folderPath)
{
this.folderPath = Path.GetDirectoryName(folderPath);
}
internal Assembly Load(string filePath)
{
FileInfo fileInfo = new FileInfo(filePath);
AssemblyName assemblyName = new AssemblyName(fileInfo.Name.Replace(fileInfo.Extension, string.Empty));
return this.Load(assemblyName);
}
protected override Assembly Load(AssemblyName assemblyName)
{
var dependencyContext = DependencyContext.Default;
var ressource = dependencyContext.CompileLibraries.FirstOrDefault(r => r.Name.Contains(assemblyName.Name));
if(ressource != null)
{
return Assembly.Load(new AssemblyName(ressource.Name));
}
var fileInfo = this.LoadFileInfo(assemblyName.Name);
if(File.Exists(fileInfo.FullName))
{
Assembly assembly = null;
if(this.TryGetAssemblyFromAssemblyName(assemblyName, out assembly))
{
return assembly;
}
return this.LoadFromAssemblyPath(fileInfo.FullName);
}
return Assembly.Load(assemblyName);
}
private FileInfo LoadFileInfo(string assemblyName)
{
string fullPath = Path.Combine(this.folderPath, $"{assemblyName}.dll");
return new FileInfo(fullPath);
}
private bool TryGetAssemblyFromAssemblyName(AssemblyName assemblyName, out Assembly assembly)
{
try
{
assembly = Default.LoadFromAssemblyName(assemblyName);
return true;
}
catch
{
assembly = null;
return false;
}
}
}
With this I'm able to load the assembly and call the projects ICompositionRootComposer implementation.
But the problem is that it doesn't seem to recognize any of my types.
When calling my configurator with
configurator.RegisterTransiantService<IFoo, Foo>();
it should register IFoo and Foo in the IoC.
But when debugging I'm not able to get info of the types, i.e via typeof(Foo) in the debug console in Visual Studio Code.
Necromancing.
You can create a wrapper class for the old Assembly.LoadFile to do that.
This has the added benefit that you can stay backward-compatible with dotnet-none-core by applying search-and-replace changes in old code-bases.
namespace System.Reflection
{
public class Assembly2
{
public static System.Reflection.Assembly LoadFile(string path)
{
System.Reflection.Assembly assembly = null;
#if NET_CORE
// Requires nuget - System.Runtime.Loader
assembly = System.Runtime.Loader.AssemblyLoadContext.Default.LoadFromAssemblyPath(path);
#else
assembly = System.Reflection. Assembly.LoadFile(path);
#endif
return assembly;
}
}
}
You'll need to add System.Runtime.Loader via NuGet.
I found a solution to my problem.
It turned out, that I had the property PreserveCompilationContext set to true, and that's why the debugger wouldn't register my manually copied assembly.
When I removed the property from the web project csproj file, everything worked.
Are you aware that ASP.NET Core has it's own, built-in Dependency Injection mechanism? It can be easily switched to other IoC container for your needs, I don't think that you need to reinvent it.
What you need to do here is use a reflection to make a generic method and call after that, something like this:
public void ConfigureServices(IServiceCollection services)
{
var myAssembly = LoadAssembly();
// find first interface
var firstInterfaceType = myAssembly.DefinedTypes.FirstOrDefault(t => t.IsInterface).GetType();
// find it's implementation
var firstInterfaceImplementationType = myAssembly.DefinedTypes.Where(t => t.ImplementedInterfaces.Contains(firstInterfaceType)).GetType();
// get general method info
MethodInfo method = typeof(IServiceCollection).GetMethod("AddTransient");
// provide types to generic method
MethodInfo generic = method.MakeGenericMethod(firstInterfaceType, firstInterfaceImplementationType);
// register your types
generic.Invoke(services, null);
}
I have a problem where I have a program that should load a plugin (DLL) from a specific directory where the DLL implements a specific base class. The problem is that my program that loads the DLL has a reference to an other DLL which the DLL being loaded also references. I will show an example of how the problem arises. This simple tests consists of 3 different solutions and 3 separate projects. NOTE: If I have all projects in the same solution, the problem does not arise.
Solution 1 - Project that defines the Base class and an interface
AdapterBase.cs
namespace AdapterLib
{
public interface IAdapter
{
void PrintHello();
}
public abstract class AdapterBase
{
protected abstract IAdapter Adapter { get; }
public void PrintHello()
{
Adapter.PrintHello();
}
}
}
Solution 2 - Project that defines an implementation of the base class
MyAdapter.cs
namespace MyAdapter
{
public class MyAdapter : AdapterBase
{
private IAdapter adapter;
protected override IAdapter Adapter
{
get { return adapter ?? (adapter = new ImplementedTestClass()); }
}
}
public class ImplementedTestClass : IAdapter
{
public void PrintHello()
{
Console.WriteLine("Hello beautiful worlds!");
}
}
}
Solution 3 - Main program which loads the DLL implementing AdapterBase*
**Program.cs
namespace MyProgram {
internal class Program {
private static void Main(string[] args) {
AdapterBase adapter = LoadAdapterFromPath("C:\\test\\Adapter");
adapter.PrintHello();
}
public static AdapterBase LoadAdapterFromPath(string dir) {
string[] files = Directory.GetFiles(dir, "*.dll");
AdapterBase moduleToBeLoaded = null;
foreach (var file in files) {
Assembly assembly = Assembly.LoadFrom(file);
foreach (Type type in assembly.GetTypes()) {
if (type.IsSubclassOf(typeof(AdapterBase))) {
try {
moduleToBeLoaded =
assembly.CreateInstance(type.FullName, false, BindingFlags.CreateInstance, null, null,
null, null) as AdapterBase;
} catch (Exception ex) {
}
if (moduleToBeLoaded != null) {
return moduleToBeLoaded;
}
}
}
}
return moduleToBeLoaded;
}
}
}
So now the main program MyProgram.cs will try to load the DLL from path C:\test\Adapter and this works fine if I ONLY put the file MyAdapter.dll in that folder. However Solution 2 (MyAdapter.cs), will put both MyAdapter.dll and AdapterBase.dll in the output bin/ directory. Now if copy both those files to c:\test\Adapter the instance from the DLL does not get loaded since the comparison
if (type.IsSubclassOf(typeof(AdapterBase))) { fails in MyProgram.cs.
Since MyProgram.cs already has a reference to AdapterBase.dll there seems to be some conflict in an other DLL gets loaded from a different path which references the same DLL. The loaded DLL seems to first resolve its dependencies against DLLs in the same folder. I think this has to do with assembly contexts and some problem with the LoadFrom method but I do not know how to get C# to realise that it actually is the same DLL which it already has loaded.
A solution is of course only to copy the only needed DLL but my program would be much more robust if it could handle that the other shared DLL also was there. I mean they are actually the same. So any solutions how to do this more robust?
Yes, this is a type identity problem. A .NET type's identity is not just the namespace and type name, it also includes the assembly it came from. Your plugin has a dependency on the assembly that contains IAdapter, when LoadFrom() loads the plugin it is also going to need that assembly. The CLR finds it in the LoadFrom context, in other words in the c:\test\adapter directory, normally highly desirable since that allows plugins to use their own DLL versions.
Just not in this case. This went wrong because you plugin solution dutifully copied the dependencies. Normally highly desirable, just not in this case.
You'll have to stop it from copying the IAdapter assembly:
Open the plugin solution and use Build > Clean.
Delete a remaining copy of the IAdapter assembly in the output directory with Explorer.
Select the IAdapter assembly in the plugin solution's References node. Set its Copy Local property to False.
Use Build > Build and verify that the IAdapter assembly indeed does not get copied anymore.
Copy Local is the essence, the rest of the bullets are there just to make sure that an old copy doesn't cause problems. Since the CLR can no longer find the IAdapter assembly the "easy way", it is forced to keep looking for it. Now finding it in the Load context, in other words, the directory where the host executable is installed. Already loaded, no need to load the one-and-only again. Problem solved.
I found a solution to my problem, although the path for the DLL can not be fully arbitrary. I was able to put the DLLs into, for example, bin/MyCustomFolder and load the DLL without getting the Type conflict problem.
The solution was to use the Assembly.Load() method which takes the full assembly name as argument. So first I find the name of the assembly by loadning all DLLs in the specified folder and the use Assembly.GetTypes() and checking if the Type is a subclass of AdapterBase. Then I use Assembly.Load() to actually load the assembly, which elegantly loads the DLL without any Type conflicts.
Program.cs
namespace MyProgram {
internal class Program {
private static void Main(string[] args) {
string codeBase = Assembly.GetExecutingAssembly().CodeBase;
UriBuilder uri = new UriBuilder(codeBase);
string path = Uri.UnescapeDataString(uri.Path);
string dir = Path.GetDirectoryName(path);
string pathToLoad = Path.Combine(dir, "MyCustomFolder");
AdapterBase adapter = LoadAdapterFromPath(pathToLoad);
adapter.PrintHello();
}
/// <summary>
/// Loads the adapter from path. LoadFile will be used to find the correct type and then Assembly.Load will be used to actually load
/// and instantiate the class.
/// </summary>
/// <param name="dir"></param>
/// <returns></returns>
public static AdapterBase LoadAdapterFromPath(string dir) {
string assemblyName = FindAssembyNameForAdapterImplementation(dir);
Assembly assembly = Assembly.Load(assemblyName);
Type[] types = assembly.GetTypes();
Type adapterType = null;
foreach (var type in types)
{
if (type.IsSubclassOf(typeof(AdapterBase)))
{
adapterType = type;
break;
}
}
AdapterBase adapter;
try {
adapter = (AdapterBase)Activator.CreateInstance(adapterType);
} catch (Exception e) {
adapter = null;
}
return adapter;
}
public static string FindAssembyNameForAdapterImplementation(string dir) {
string[] files = Directory.GetFiles(dir, "*.dll");
foreach (var file in files)
{
Assembly assembly = Assembly.LoadFile(file);
foreach (Type type in assembly.GetTypes())
{
if (type.IsSubclassOf(typeof(AdapterBase)))
{
return assembly.FullName;
}
}
}
return null;
}
}
}
NOTE: It is also important to add the extra probing path for Assembly.Load() to find the assembly in bin/MyCustomFolder. The probing path must be a subdir of the executing assembly, therefore it is not possible to have the DLL in a completely arbitrary location. Update your App.config as below:
App.config
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<probing privatePath="MyCustomFolder"/>
</assemblyBinding>
</runtime>
</configuration>
Tip: Actually I was having this problem for a Web application I had created. In that case you should update Web.config instead. Also in that case the probing path does not have the executing assembly as root but is actually the root of your web application. So in that case you can put you DLL folder MyCustomFolder directly in you web apps root folder, for example: inetpub\wwwroot\mywebapp\MyCustomFolder and then update Web.config as App.config above.
I have couple of class libraries in my project and all are using Ninject IoC container. I wanted to load all the modules in a StandardKernel at one go wherever an INinjectModule is found. So I used:
var kernel = new StandardKernel();
kernel.Load(AppDomain.CurrentDomain.GetAssemblies())
But this doesn't work for some reason. Can anyone help?
Well, this often happens when bindings are declared but other modules are loaded where that module tries to resolve a binding which has not loaded yet. This happens because List<INinjectModule> may not in the right order.
If you think this is the case. Follow this resolution.
The idea is we will have a bootstapper for each assembly, where the bootstrapper will be responsible to load the modules in its logical order.
Let us consider an interface for bootstrapper (this we will use to find the bootstrapper in an assembly)
public interface INinjectModuleBootstrapper
{
IList<INinjectModule> GetModules();
}
Now consider for your DataAccess assembly, implement the INinjectModuleBootstrapper:
public class DataAccessBootstrapper : INinjectModuleBootstrapper
{
public IList<INinjectModule> GetModules()
{
//this is where you will be considering priority of your modules.
return new List<INinjectModule>()
{
new DataObjectModule(),
new RepositoryModule(),
new DbConnectionModule()
};
//RepositoryModule cannot be loaded until DataObjectModule is loaded
//as it is depended on DataObjectModule and DbConnectionModule has
//dependency on RepositoryModule
}
}
This is how you defne the Bootstrapper for all your assembly. Now, from your program startup, we need the StandardKernel where all the modules are loaded. We will write something like this:
var assemblies = AppDomain.CurrentDomain.GetAssemblies();
return BootstrapHelper.LoadNinjectKernel(assemblies);
And our BootstrapperHelper class is:
public static class BootstrapHelper
{
public static StandardKernel LoadNinjectKernel(IEnumerable<Assembly> assemblies)
{
var standardKernel = new StandardKernel();
foreach (var assembly in assemblies)
{
assembly
.GetTypes()
.Where(t =>
t.GetInterfaces()
.Any(i =>
i.Name == typeof(INinjectModuleBootstrapper).Name))
.ToList()
.ForEach(t =>
{
var ninjectModuleBootstrapper =
(INinjectModuleBootstrapper)Activator.CreateInstance(t);
standardKernel.Load(ninjectModuleBootstrapper.GetModules());
});
}
return standardKernel;
}
}
Another thing you should check is if the class that extends NinjectModule is public, otherwise it wont be visible in the Assembly.
I think that is not a good idea to use CurrentDomain.GetAllAssemblies() because not all project assemblies can be loaded on program startup ( some assemblies can be loaded on user actions for example or other events). In this case you will have null-reference exceptions for dependencies.
You can use reflection to find and instantiate the Ninject modules:
BuildManager.GetReferencedAssemblies()
.Cast<Assembly>()
.SelectMany(a => a.DefinedTypes)
.Where(t => typeof(INinjectModule).IsAssignableFrom(t))
.Select(t => (INinjectModule)Activator.CreateInstance(t))