Loading modules in all assemblies in Ninject

后端 未结 4 1077
遥遥无期
遥遥无期 2021-01-31 06:12

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

4条回答
  •  粉色の甜心
    2021-01-31 06:26

    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 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 GetModules();
    }
    

    Now consider for your DataAccess assembly, implement the INinjectModuleBootstrapper:

    public class DataAccessBootstrapper : INinjectModuleBootstrapper
    {
        public IList GetModules()
        {
            //this is where you will be considering priority of your modules.
            return new List()
                       {
                           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 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;
        }
    }
    

提交回复
热议问题