0

我是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,他们会将所有注入添加到其中。

4

1 回答 1

1

这是可行的。

我通常创建一个单独的“CompostionRoot”项目,它本身引用我的中央接口和具体的业务/服务/数据层等,然后将 Ninject 添加到它,将此项目的引用添加到我的 MVC/WebAPI 项目,然后最后通过内核来自 Ninject.Web.CommonRegisterServices函数

IE

using CompositionRoot; 
...
...

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

现在这可能不被认为是“最佳实践”,但我喜欢这种方法的一点是,我对 MVC 项目中的具体业务/服务/数据层实现完全没有依赖关系——一切都可以通过接口完成,只需引用我的接口来自 MVC 项目的项目,加上该项目可以在其他解决方案中重用。我想这只是一个额外的间接层,到目前为止我还没有遇到任何这样做的缺点......

希望有帮助。

于 2013-10-12T15:17:09.713 回答