C# 其他层中的依赖项发现';使用Ninject.MVC3的s模块

C# 其他层中的依赖项发现';使用Ninject.MVC3的s模块,c#,asp.net-mvc-4,ninject,C#,Asp.net Mvc 4,Ninject,主要问题:如何发现在其他层中配置了Ninject.MVC3的依赖关系 背景: 我正在我的一个ASP.NET MVC4项目中使用Ninject.MVC3 我以前使用过ServiceLocator,但对Ninject来说是新的。通过新的增强功能,Ninject的设置和配置非常简单 在新的Ninject.MVC3 Nuget包中,将一个“NinjectWebCommon”类添加到web项目的App_Start文件夹中,我们在其中配置所有依赖项。这个类是静态的,除了返回void的Start和Stop静态

主要问题:如何发现在其他层中配置了Ninject.MVC3的依赖关系

背景:

我正在我的一个ASP.NET MVC4项目中使用Ninject.MVC3

我以前使用过ServiceLocator,但对Ninject来说是新的。通过新的增强功能,Ninject的设置和配置非常简单

在新的Ninject.MVC3 Nuget包中,将一个“
NinjectWebCommon
”类添加到web项目的App_Start文件夹中,我们在其中配置所有依赖项。这个类是静态的,除了返回void的Start和Stop静态方法外,不公开任何外部内容

为了使用它,您可以在其“
RegisterServices
”方法中配置依赖项,例如

    private static void RegisterServices(IKernel kernel)
    { 
        kernel.Bind<IDataContext>().To<MyDataContext>().WithConstructorArgument("connectionString", "name=MyDataContext");

        kernel.Bind<IRoleService>()
        .To<RoleService>()
        .WithConstructorArgument("dbContext", context => context.Kernel.Get<IDataContext>());
    }
现在假设我们想向这个类添加一个新的依赖项,比如ILogger
RoleService
。目前我必须这样做:

public class RoleService : IRoleService
{
    private readonly IDataContext _dbContext;
    private ILogger _logger;

    public RoleService(IDataContext dbContext, ILogger logger)
    {
        _dbContext = dbContext;
        _logger = logger;
    }
}
我想知道这是允许模块发现依赖关系的唯一(或理想或标准)方法吗

使用
ServiceLocator
我会这样做:

    public class RoleService : IRoleService
    {
        private readonly IDataContext _dbContext;
        private readonly Lazy<ILogger> _logger;        

        public RoleService(IDataContext dbContext)
        {
            _dbContext = dbContext;
            _logger = Locator.Current.GetInstanceLazy<ILogger>();
        }
    }
在存在于业务层中的RoleService类中。该属性未初始化并设置为null。我应该如何使Ninject初始化它,请注意Ninject初始化是在MVCWeb项目中完成的

总结我的问题如下:

  • 从这两个构造函数到属性注入w.r.t.Ninject MVC3包,有什么更好的方法

  • 有没有其他方法可以像使用ServiceLocator一样在业务层类中发现依赖关系

  • 在上述情况下,财产注入应该如何工作

  • 提前感谢。

    1)我更喜欢构造器,因为它给我提供了更好的概述,我习惯了它
    2) 您应该在层的底部创建StandardKernel对象集,包括UI项目在内的每个组件都应该使用该对象
    3) 您必须通过ninject进行实例化。Ninject将填充构造函数参数,并搜索属性注入的类型。
    例如:

      public interface IBusinessClass {
        int DoWork();
      }
    
      public class BusinessClass : IBusinessClass
      {
        public int DoWork()
        {
          return 10;
        }
      }
      public interface IBusinessClass2
      {
        int DoWork2();
      }
    
      public class BusinessClass2 : IBusinessClass2
      {
        public int DoWork2()
        {
          return 20;
        }
      }
      public class Consumer
      {
        public IBusinessClass2 BusinessClass2 { get; set; }
    
        [Inject]
        public IBusinessClass BusinessClass { get; set; }
    
        public Consumer(IBusinessClass2 businessClass2)
        {
          BusinessClass2 = businessClass2;
        }
      }
      class Program
      {
        static void Main(string[] args)
        {
          IKernel kernel = new StandardKernel();
          kernel.Bind<IBusinessClass>()
                .To<BusinessClass>();
          kernel.Bind<IBusinessClass2>()
                .To<BusinessClass2>();
    
          Consumer c = kernel.Get<Consumer>();
          Console.WriteLine(c.BusinessClass.DoWork());
          Console.WriteLine(c.BusinessClass2.DoWork2());
          Console.ReadKey();
        }
      }
    
    修改此方法n以使用新内核,但不使用基本库中的内核:

    private static IKernel CreateKernel()
    {
        var kernel = // kernel from base library
        kernel.Bind<Func<IKernel>>().ToMethod(ctx => () => new Bootstrapper().Kernel);
        kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>();
    
        RegisterServices(kernel);
        return kernel;
    }
    
    private静态IKernel CreateKernel()
    {
    var kernel=//来自基本库的内核
    kernel.Bind().ToMethod(ctx=>()=>newbootstrapper().kernel);
    kernel.Bind().To();
    注册服务(内核);
    返回内核;
    }
    
    谢谢你,彼得。考虑到我们有多层arch,我们应该创建一个单独的库项目,在其中添加Ninject并使用依赖项配置它。在预启动或启动期间的web项目中,我们将初始化这个新库。我做对了吗?现在要尝试一下……您可以在其他库中使用webactivator:[assembly:WebActivatorEx.PreApplicationStartMethod(typeof(className),“parameterlessStaticMethodOfThatClass”)]创建了一个单独的库项目,并在其中安装了Ninject。配置了一个依赖项。Web项目具有对此程序集的引用,正在调用调试启动方法。但是,现在没有调用具有参数的控制器ctor。“没有为此对象定义无参数构造函数。”我将[Inject]放在控制器ctor中,但存在相同的问题。我想我必须做些额外的事情,让Ninject在项目之间共享,并进行探索。有什么建议吗?再次感谢@Péter。这听起来是一个很有吸引力的解决方案。我将在今天实施并接受您的回答。谢谢
      public interface IBusinessClass {
        int DoWork();
      }
    
      public class BusinessClass : IBusinessClass
      {
        public int DoWork()
        {
          return 10;
        }
      }
      public interface IBusinessClass2
      {
        int DoWork2();
      }
    
      public class BusinessClass2 : IBusinessClass2
      {
        public int DoWork2()
        {
          return 20;
        }
      }
      public class Consumer
      {
        public IBusinessClass2 BusinessClass2 { get; set; }
    
        [Inject]
        public IBusinessClass BusinessClass { get; set; }
    
        public Consumer(IBusinessClass2 businessClass2)
        {
          BusinessClass2 = businessClass2;
        }
      }
      class Program
      {
        static void Main(string[] args)
        {
          IKernel kernel = new StandardKernel();
          kernel.Bind<IBusinessClass>()
                .To<BusinessClass>();
          kernel.Bind<IBusinessClass2>()
                .To<BusinessClass2>();
    
          Consumer c = kernel.Get<Consumer>();
          Console.WriteLine(c.BusinessClass.DoWork());
          Console.WriteLine(c.BusinessClass2.DoWork2());
          Console.ReadKey();
        }
      }
    
    private static IKernel CreateKernel()
    {
        var kernel = new StandardKernel();
        kernel.Bind<Func<IKernel>>().ToMethod(ctx => () => new Bootstrapper().Kernel);
        kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>();
    
        RegisterServices(kernel);
        return kernel;
    }
    
    private static IKernel CreateKernel()
    {
        var kernel = // kernel from base library
        kernel.Bind<Func<IKernel>>().ToMethod(ctx => () => new Bootstrapper().Kernel);
        kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>();
    
        RegisterServices(kernel);
        return kernel;
    }