用于MVC的Ninject 101

时间:2010-11-11 13:14:11

标签: asp.net-mvc ninject

我是Ninject的新手并试图找出实施方案。我正在搜索和阅读,任何人都可以向我指出一些特定于Ninject和MVC的优秀示例和文档。

我可以使用基础知识,我正在努力处理具有依赖关系的Bindings。例如,我有以下类:

  public class ScheduleService : IScheduleService
    {
        private IValidationDictionary validationDictionary;
        public ScheduleService(IValidationDictionary validationDictionary)
         {
             this.validationDictionary = validationDictionary;
         }
    }

这取决于:

public class ModelStateWrapper : IValidationDictionary
    {
        private ModelStateDictionary _modelState;

        public ModelStateWrapper(ModelStateDictionary modelState)
        {
            _modelState = modelState;
        }

我想为:

创建绑定
 Bind<IValidationDictionary>()
                    .To<ModelStateWrapper>();

                Bind<IScheduleService>()
                    .To<ScheduleService>();

如何设置绑定,以便我的控制器可以使用ScheduleService?它是如何获得ModelState的?

澄清: 我想将此注入到调度服务类中,该类处理业务逻辑。我有Ninject工作,只是不知道如何处理依赖项。下面是我的控制器代码。

public class ScheduleController : ActivityController
{
    private IScheduleService scheduleService;


    public ScheduleController(IScheduleService scheduleService)
    {
        this.scheduleService = new ScheduleService(new ModelStateWrapper(this.ModelState));
    }

感谢您的耐心等待,我可能不会问正确的问题。它构建但是当我运行它时,我得到:

激活IValidationDictionary时出错 没有匹配的绑定可用,并且该类型不可自绑定。 激活路径:  3)将依赖IValidationDictionary注入到ScheduleService类型的构造函数的参数validationDictionary中  2)将依赖项IScheduleService注入到ScheduleController类型的构造函数的参数scheduleService中  1)请求ScheduleController

建议:  1)确保已为IValidationDictionary定义了绑定。  2)如果在模块中定义了绑定,请确保已将模块加载到内核中。  3)确保您没有意外创建多个内核。  4)如果使用自动模块加载,请确保搜索路径和过滤器正确无误。

3 个答案:

答案 0 :(得分:3)

你的意思是:

设置Ninject2

public class MvcApplication : NinjectHttpApplication
{
    public static void RegisterRoutes(RouteCollection routes)
    {
        //Here goes routing setup
    }

    protected override void OnApplicationStarted()
    {
        RegisterRoutes(RouteTable.Routes);
        RegisterAllControllersIn(Assembly.GetExecutingAssembly());
    }

    protected override IKernel CreateKernel()
    {
        return new StandardKernel(new ServiceModule());
    }
}

internal class ServiceModule : NinjectModule
{
    public override void Load()
    {
        Bind<IValidationDictionary>().To<ModelStateWrapper>();
        Bind<IScheduleService>().To<ScheduleService>();
    }
}

注入控制器

public class HomeController : Controller
{
    private readonly IValidationDictionary _validationDictionary;
    private readonly IScheduleService _scheduleService;

    public HomeController(IValidationDictionary validationDictionary, IScheduleService scheduleService)
    {
        _validationDictionary = validationDictionary;
        _scheduleService = scheduleService;
    }
}

答案 1 :(得分:1)

你真的不能这样做。模型状态是控制器在初始化时设置的。我不知道Ninject,但您应该能够对服务进行上下文解析并将其传递给当前的模型状态。这不是一个很好的解决方案,我不推荐它。

基本上你的问题是Ninject不知道如何解决ModelStateDictionary,因为你没有告诉它如何。如果对你的modelstatewrapper类的依赖是另一个不是上下文的东西那么你只需要在Ninject中设置它以使它工作。

答案 2 :(得分:1)

您可能考虑的一件事是注入工厂来生产IValidationDictionary。例如,你的控制器构造函数将采用IValidationFactory,而IValidationFactory有一个方法:GetValidation(ModelStateDictionary modelState),你的默认实现返回你的ModelStateWrapper。这允许你完整的IoC,你可以注入你自己的存根进行单元测试。

如果IValidationDictionary上只有一个或两个方法,你也可以将ModelState传递给被调用的方法,而不是试图将它注入构造函数。