MVC3, Ninject and Ninject.MVC3 problem

2019-01-25 00:50发布

问题:

I just start using Ninject with MVC3 so here is my problem: - I installed Ninject 2.2.1.4 and Ninject.MVC3 2.2.2.0 from Nuget - In my WebUI (MVC3 project):

Global.asax.cs

public class MvcApplication : NinjectHttpApplication
{
    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        filters.Add(new HandleErrorAttribute());
    }

    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        routes.MapRoute(
            "Default", // Route name
            "{controller}/{action}/{id}", // URL with parameters
            new { controller = "home", action = "index", id = UrlParameter.Optional } // Parameter defaults
        );

    }

    protected override void OnApplicationStarted()
    {
        base.OnApplicationStarted();

        AreaRegistration.RegisterAllAreas();
        RegisterGlobalFilters(GlobalFilters.Filters);
        RegisterRoutes(RouteTable.Routes);
    }

    protected override IKernel CreateKernel()
    {
        var kernel = new StandardKernel();
        kernel.Load(Assembly.GetExecutingAssembly());
        return kernel;
    }


}
  • In my Domain (class project), i have my LinQ to SQL datacontext, i want to load the context with the connection string from my Web.Config in my WebUI, so i have to pass the constructor parameter, i also have some services in my Domain project

    public class LotteryDataService
    {
        LinQ.WebDataContext _context;
    
        public LotteryDataService(LinQ.WebDataContext context)
        {
            _context = context;
        }
    
        public IEnumerable<LinQ.LotteryData> Get()
        {
            return _context.LotteryDatas.Take(10);
        }
    }
    

How to bind the datacontext with Ninject with constructor parameter (here is connection string)?

回答1:

This is how you pass a constructor parameter. Ninject will resolve the constructor that matches the specified constructor arguments.

public class DataModule : NinjectModule
{
    public override void Load()
    {
        string connectionString = "...";
        Bind<WebDataContext>().ToSelf()
            .WithConstructorArgument("connection", connectionString);
    }
}

The first argument to .WithConstructorArgument() should be the name of the constructor parameter. This is fileOrServerOrConnection in the base class, but connection in derived class.



回答2:

Below code snap might be helpful. Hope it will serve greater flexibility!

public class MvcModule : NinjectModule
{
    //Bind the default connection string
    public void BindDataContext()
    {
        ConstructorArgument parameter = new ConstructorArgument("connectionString", "[Config Value]");
        Bind<DataContext>().ToSelf().InRequestScope().WithParameter(parameter);
    }
    public override void Load()
    {
         BindDataContext();
         Bind(typeof(IRepository<>)).To(typeof(EntityRepository<>)).InRequestScope();
         ........
    }
    //Re-Bind the connection string (in case of multi-tenant architecture)
    public void ReBindDataContext(string cn)
    {
         ConstructorArgument parameter = new ConstructorArgument("connectionString", cn);
         Rebind<DataContext>().ToSelf().InRequestScope().WithParameter(parameter);
    }
    //Re-Bind the connection string (in case of multi-tenant architecture)
    public static void ReBindDataContext(IKernal kernel,string cn)
    {
         IEnumerable<INinjectModule> ml = kernel.GetModules();
         var myModule = ml.Where(i => i.Name.ToLowerInvariant().Contains("mvcmodule")).Select(i => i).Take(1);
         MvcModule mm = myModule.ToList()[0] as MvcModule ;
         mm.ReBindDataContext(cn);
    }
    //Return the module, for further modification like connection string
    public static MvcModule GetModule(IKernal kernel)
    {
        IEnumerable<INinjectModule> ml = kernel.GetModules();
        var myModule = ml.Where(i => i.Name.ToLowerInvariant().Contains("mvcmodule")).Select(i => i).Take(1);
        MvcModule mm = myModule.ToList()[0] as MvcModule ;
        return mm;
    }
}