Ninject 到 Webactivator 调用的类中

发布于 2024-12-12 04:17:16 字数 911 浏览 3 评论 0原文

我使用 nuget 模板方式来注入我的 MVC3 应用程序, 这意味着我使用 WebActivator 调用静态类上的方法,该方法又创建 Ninject 引导程序并连接到 MVC3。

这对于控制器、适配器等来说效果很好。但我想要另一个 Webactivator 激活的类,它使用 Ninject 获取其依赖项。

我让它与穷人的解决方案一起工作,但我更喜欢更优雅的解决方案。

首先,我确保我的 Webactivator 类使用 PostApplicationStartMethod 调用,因为 Ninject 模块使用 PreApplicationStartMethod,我可以确保 ninject 已加载并准备好运行。然后在 Start 方法中我做的

var workers = DependencyResolver.Current.GetServices<IWorker>();

为了获取我的依赖项,整个类看起来像这样

[assembly: WebActivator.PostApplicationStartMethod(typeof(SHB.DALA.Web.App_Start.WorkflowRunner), "Start")]

namespace SHB.DALA.Web.App_Start
{
    public static class WorkflowRunner 
    {
        public static void Start()
        {
            var workers = DependencyResolver.Current.GetServices<IWorker>();
            //Do stuff with worker collection
        }
    }
}

一定有更优雅的解决方案吧?

I use the nuget template way of ninjectning my MVC3 app,
which means I have use WebActivator to invoke a method on a static class that in turn creates a Ninject bootstrapper and hooks up to MVC3.

That works fine for Controller, adapters etc. But I want to have another Webactivator activated class which gets its dependencies using Ninject.

I got it to work with a poor mans solution, but I would prefer a more elegant solution.

First I make sure my Webactivator class uses the PostApplicationStartMethod invoke, since the Ninject module uses the PreApplicationStartMethod I can ensure that ninject has been loaded and is ready to go.. THen in the Start method I do

var workers = DependencyResolver.Current.GetServices<IWorker>();

To get my dependencies, the whole class looks like this

[assembly: WebActivator.PostApplicationStartMethod(typeof(SHB.DALA.Web.App_Start.WorkflowRunner), "Start")]

namespace SHB.DALA.Web.App_Start
{
    public static class WorkflowRunner 
    {
        public static void Start()
        {
            var workers = DependencyResolver.Current.GetServices<IWorker>();
            //Do stuff with worker collection
        }
    }
}

There must be a more elegant solution right?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

薄荷港 2024-12-19 04:17:16

WebActivator(实际上是 ASP.NET)对 Ninject 项目没有任何了解,因此无法注入任何参数。您需要一个 Ninject WebActivator 扩展(与 Ninject MVC 扩展的方式相同)来实现它。但坦率地说,这有点像第 22 条军规:您希望 WebActivator 设置 Ninject,同时让 Ninject 设置 WebActivator。

我可以为您想到 2 种可能的情况:

  1. 保留代码原样 - 老实说,我不知道为什么您不喜欢您的 WorkflowRunner 类。这是一个很好的小类,没有其他代码对它有任何依赖,您通过 DependencyResolver 获取引用,它从 Ninject 本身抽象您,您的工作流程初始化被很好地封装在那里。我真的没有闻到任何问题。

  2. 在另一个 WebActivator 类中初始化您的工作流程,其中设置 Ninject。您知道您的 Ninject 已初始化,并且您仍然可以将工作流初始化代码保留在单独的类中。

如果我是你,我显然会选择 1。

WebActivator (ASP.NET really) doesn't have any knowledge of Ninject project and therefore cannot have any parameters injected. You would need a Ninject WebActivator extension (the same way you have a Ninject MVC extension) to achieve it. But frankly this is a bit of a catch-22: you want WebActivator to setup Ninject and at the same time Ninject to setup WebActivator.

I can think of 2 possible scenarios for you:

  1. leave the code as it is - I honestly don't know why you don't like your WorkflowRunner class. It is a nice, small class, no other code has any dependency on it, You obtain your references through a DependencyResolver which abstracts you from Ninject itself, your workflow initialization is nicely encapsulated there. I do not smell anything wrong here, really.

  2. Initialize your workflows in the other WebActivator class, where setup Ninject. You know there that your Ninject is initialized and you can still keep workflow initialization code in a separate class.

I would obviously choose 1. if I were you.

梦归所梦 2024-12-19 04:17:16

如果您已经让 Ninject 引导程序正常工作,您确定需要其他解决方案吗?对于非控制器依赖项,我使用具有 GetInstance() 方法的 BindingFactory 类。这只是调用 Kernel 对象上的 Get() 方法。

public class BindingFactory
{
    private static readonly IKernel Kernel = new StandardKernel(new DefaultServices());

    public static T GetInstance<T>()
    {
        return Kernel.Get<T>();
    }

    public static IController GetControllerInstance(Type controllerType)
    {
        return Kernel.Get(controllerType) as IController;
    }
}

然后我使用 NinjectControllerFactory,它利用了 BindingFactory。

public class NinjectControllerFactory : DefaultControllerFactory
{
    protected override IController GetControllerInstance(RequestContext context, Type controllerType)
    {
        if (controllerType == null)
            return null;

        return BindingFactory.GetControllerInstance(controllerType);
    }
}

所以我想你可以调整你当前的实现。

If you already have the Ninject bootstrapper working, are you sure you need another solution? For non-controller dependencies, I use a BindingFactory class which has a GetInstance() method. This just calls the Get() method on the Kernel object.

public class BindingFactory
{
    private static readonly IKernel Kernel = new StandardKernel(new DefaultServices());

    public static T GetInstance<T>()
    {
        return Kernel.Get<T>();
    }

    public static IController GetControllerInstance(Type controllerType)
    {
        return Kernel.Get(controllerType) as IController;
    }
}

I then use a NinjectControllerFactory which utilises the BindingFactory.

public class NinjectControllerFactory : DefaultControllerFactory
{
    protected override IController GetControllerInstance(RequestContext context, Type controllerType)
    {
        if (controllerType == null)
            return null;

        return BindingFactory.GetControllerInstance(controllerType);
    }
}

So I'm thinking you could just adapt your current implementation.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文