How to tell Ninject to bind to an implementation it doesn't have a reference to

北慕城南 提交于 2019-12-03 08:05:24

To get you pointed in the right direction, I'd suggest you take a look at the onion architecture.

It's basic premise is that any code can depend on layers more central. In your scenario (and it's a common one for MVC3 apps using the Repository pattern) your UI should have a reference to the services layer and it's acceptable to have a reference to the data layer.

If you're willing to accept that (it's a hard pill to swallow if you're coming from a classic N-tier setup, I know), then your situation becomes much simpler.

With Ninject you now do something as follows:

In your NinjectMVC3.cs file your CreateKernel becomes

    /// <summary>
    /// Creates the kernel that will manage your application.
    /// </summary>
    /// <returns>The created kernel.</returns>
    private static IKernel CreateKernel()
    {
        var modules = new INinjectModule[]
                          {
                              new ServiceDIModule(),
                              new RepositoryDIModule()
                          };

        var kernel = new StandardKernel(modules);

        //RegisterServices(kernel); <-- Only if you have some custom binding 
        //                              that are UI specific
        return kernel;
    }

Now, in your services layer, you add a reference to Ninject (just plain Ninject via NuGet, not the MVC3 dropin via NuGet) and add what I called above the ServiceDIModule which looks like this:

using Ninject.Modules;

namespace MyServiceLayer
{
    public class ServiceDIModule : NinjectModule
    {
        public override void Load()
        {
            //Bind Services
            Bind<IPracticeService>().To<PracticeService>().InRequestScope();
        }
    }
}

and you repeat the same process for the Data Tier injections you may have (UnitofWork, DatabaseFactory, IFooRepository, etc.)

namespace MyDataLayer
{
    public class RepositoryDIModule : NinjectModule
    {
        public override void Load()
        {
            //Bind Repos
            Bind<IFooRepository>().To<FooRepository>().InRequestScope();
        }
    }
}

Now, you have access to all of the bindings you need way upfront. So, your question to me really boils down to a shift in thinking. If you can accept (begrudgingly or otherwise) the onion concept, your scenario resolves itself cleanly.

You can also check out Project Silk and CodeCampServer. They both implement the "onion" concept to some degree (Silk for sure, I'm looking at the solution right now and the UI web project contains a ref to the Data proj which contains all the Repos)

Let me know what you think.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!