Ninject和包装服务,基础设施和数据层

时间:2013-10-12 14:32:20

标签: c# dependency-injection ninject

我是ninject的巨大粉丝。但到目前为止,我只用它进行单次注射。我目前想要打包我创建的服务基础架构和数据层。

基本上我的基础架构层有合同用于创建我的服务层需要传递给数据层的存储过程Dao。数据层使用添加到DAO的参数执行SP调用并返回数据集。所有这些都很有效。

我在所有这三个上使用基于构造函数的依赖注入,我想用它们预先打包IOC。这样,当我在另一个应用程序中使用它时,我不必为dll中的类重新连接依赖注入。

每次我使用ninject时,我都会连接一个ninject webcommon,它从上到下完成整个应用程序。

namespace MyApp.App_Start
{
    using System;
    using System.Web;

    using Microsoft.Web.Infrastructure.DynamicModuleHelper;

    using Ninject;
    using Ninject.Web.Common;

    public static class NinjectWebCommon 
    {
        private static readonly Bootstrapper bootstrapper = new Bootstrapper();

        /// <summary>
        /// Starts the application
        /// </summary>
        public static void Start() 
        {
            DynamicModuleUtility
                .RegisterModule(typeof(OnePerRequestHttpModule));

            DynamicModuleUtility
                .RegisterModule(typeof(NinjectHttpModule));

            bootstrapper.Initialize(CreateKernel);
        }

        /// <summary>
        /// Stops the application.
        /// </summary>
        public static void Stop()
        {
            bootstrapper.ShutDown();
        }

        /// <summary>
        /// Creates the kernel that will manage your application.
        /// </summary>
        /// <returns>The created kernel.</returns>
        private static IKernel CreateKernel()
        {
            var kernel = new StandardKernel();
            AutoMapper.AutoMapperConfigurator.Configure();

            try
            {
                kernel.Bind<Func<IKernel>>()
                    .ToMethod(ctx => () => new Bootstrapper().Kernel);
                kernel.Bind<IHttpModule>()
                    .To<HttpApplicationInitializationHttpModule>();

                RegisterServices(kernel);
                return kernel;
            }
            catch
            {
                kernel.Dispose();
                throw;
            }
        }

        /// <summary>
        /// Load your modules or register your services here!
        /// </summary>
        /// <param name="kernel">The kernel.</param>
        private static void RegisterServices(IKernel kernel)
        {
            kernel.Bind<IQuerySelector>().To<QuerySelector>();
            kernel.Bind<IQueryExecutor>().To<QueryExecutor>();
            kernel.Bind<ISqlParameterPopulationService>()
                .To<SqlParameterPopulationService>();
        }        
    }

我想在预先包装的Dll中有一个IOC,开发人员无法访问,然后用户可以拥有自己的IOC,他们会将所有注入添加到其中。

1 个答案:

答案 0 :(得分:1)

这是可行的。

我通常创建一个单独的“CompostionRoot”项目,它本身引用我的中央界面和具体的业务/服务/数据层等,然后将Ninject添加到它,将此项目的引用添加到我的MVC / WebAPI项目,然后最后从RegisterServices函数

中的Ninject.Web.Common传递内核

using CompositionRoot; 
...
...

private static void RegisterServices(IKernel kernel)
        {
            var cr = new MyExternalComposer(kernel);
            cr.DoBindings();
        }  

现在这可能不被认为是“最佳实践”,但我喜欢这种方法的是我对MVC项目的具体业务/服务/数据层实现没有依赖性 - 一切都可以通过接口来完成从MVC项目引用我的Interfaces项目,以及该项目可以在其他解决方案中重用。我想这只是一个额外的间接层,到目前为止,我没有遇到任何弊端......

希望有所帮助。