忍者+ ASP.NET Web 表单不工作

发布于 2024-12-05 12:01:03 字数 2007 浏览 1 评论 0原文

我已经在 MVC3 应用程序中成功实现了 Ninject,但在使用 ASP.NET Web 窗体执行同样的操作时遇到了一些麻烦。每次尝试访问业务层中的注入属性时,我都会收到空引用。在 CreateKernel 方法中以及 ServiceLocator 类中的多个位置设置断点后,看起来它们都没有被击中,因此它甚至没有加载。

我确信我的做法是错误的,但是在 Web 表单应用程序中连接 Ninject 的文档或信息非常少。

基本上这就是我到目前为止所拥有的:

代码隐藏

public class ReviewManager
    {
        [Inject] private IReviewRepository _reviewRepository { get; set; }

        public ReviewManager() { }

        public ReviewManager(IReviewRepository reviewRepository)
        {
            _reviewRepository = reviewRepository;
        }

        public Review GetById(int id)
        {
            if (id <= 0) throw new ArgumentException("ID must be greater than zero");

            **I get a null reference exception on the next line. _reviewRepository is null**
            return _reviewRepository.GetById(id);
        }
}

global.asax.cs

public class Global : NinjectHttpApplication
{
    protected override IKernel CreateKernel()
    {
        return ServiceLocator.Kernel;
    }

    // deleted for brevity
}

ServiceLocator.cs (为简洁起见,相关部分位于此处)

public static class ServiceLocator
    {
        public static IKernel Kernel { get; set; }

        public static ILogger Logger { get; set; }

        static ServiceLocator()
        {
            Kernel = new StandardKernel(new INinjectModule[] {
                new LoggerBindings(),
                new DataBindings()
            });

            if (Logger == null)
                Logger = Kernel.Get<ILogger>();
        }
}
public class LoggerBindings : NinjectModule
    {
        public override void Load()
        {
            Bind<ILogger>().To<NLogLogger>();
        }
    }

    public class DataBindings : NinjectModule
    {
        public override void Load()
        {
            Bind<IReviewRepository>().To<ReviewRepository>();
        } 
    }

I've successfully implemented Ninject in an MVC3 application, but am running into some trouble doing the same thing with ASP.NET Web Forms. I'm getting null references every time I try to access an injected property in my business layer. After setting breakpoints within the CreateKernel method, as well as several places within the ServiceLocator class, it looks like none of them are ever getting hit, so it's not even loading.

I'm sure I'm just approaching this wrong, but there is very little documentation or info out there for wiring up Ninject in a Web Forms application.

Basically here's what I have so far:

code behind

public class ReviewManager
    {
        [Inject] private IReviewRepository _reviewRepository { get; set; }

        public ReviewManager() { }

        public ReviewManager(IReviewRepository reviewRepository)
        {
            _reviewRepository = reviewRepository;
        }

        public Review GetById(int id)
        {
            if (id <= 0) throw new ArgumentException("ID must be greater than zero");

            **I get a null reference exception on the next line. _reviewRepository is null**
            return _reviewRepository.GetById(id);
        }
}

global.asax.cs

public class Global : NinjectHttpApplication
{
    protected override IKernel CreateKernel()
    {
        return ServiceLocator.Kernel;
    }

    // deleted for brevity
}

ServiceLocator.cs (edited for brevity, the relevant parts are here)

public static class ServiceLocator
    {
        public static IKernel Kernel { get; set; }

        public static ILogger Logger { get; set; }

        static ServiceLocator()
        {
            Kernel = new StandardKernel(new INinjectModule[] {
                new LoggerBindings(),
                new DataBindings()
            });

            if (Logger == null)
                Logger = Kernel.Get<ILogger>();
        }
}
public class LoggerBindings : NinjectModule
    {
        public override void Load()
        {
            Bind<ILogger>().To<NLogLogger>();
        }
    }

    public class DataBindings : NinjectModule
    {
        public override void Load()
        {
            Bind<IReviewRepository>().To<ReviewRepository>();
        } 
    }

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

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

发布评论

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

评论(4

峩卟喜欢 2024-12-12 12:01:03

通过 WebForms 的 ASP.Net 不允许您管理所有对象实例的生命周期(像 MVC 那样)。例如,框架实例化页面对象。这意味着您可能无法以与在 MVC/WPF/Silverlight 中完全相同的方式实现 DI(WinForms IIRC 中也存在同样的问题)。您可能必须直接在每个后面的代码中启动依赖关系图。

翻译:您需要在页面加载时调用 ServiceLocator.Kernel.Get (或作为属性上的惰性初始化)。

ASP.Net via WebForms does not allow you to manage the lifecycle of all object instances (like MVC does). For example, the framework instantiates page objects. This means you probably can't implement DI in quite the same way as you would in MVC/WPF/Silverlight (the same problem is present in WinForms IIRC). You will likely have to initiate the dependency graph directly in each of your code behinds.

Translation: you will want to call ServiceLocator.Kernel.Get<IReviewRepository> when your page loads (or as lazy-init on the property).

泪意 2024-12-12 12:01:03

MVC 的一个很酷的地方是它可以在同一个应用程序中同时运行 ASP.NET WebForm 页面。在我看来,扩展 ASP.NET WebForms 网站的最佳方法是使用 MVC3 创建新页面,并重构每个需要对 MVC3 进行重大更改的页面。

如果这不是选项,请使用 Ninject.Web 扩展。它包含一个 IHttpModule,该属性在初始化后注入所有网页和控件。这样您就可以属性注入由 Ninject 创建的服务。

The cool thing about MVC ist that it can run side a side of ASP.NET WebForm pages in the same application. In my opinion the best way to extend ASP.NET WebForms websites is to create new pages using MVC3 and to refactor every page that needs major changes to MVC3.

If this is no option go and use the Ninject.Web extension. It contains a IHttpModule that property injects all web pages and controlls after they are initialized. That way you can property inject the services als have them created by Ninject.

原谅我要高飞 2024-12-12 12:01:03

一个潜在的解决方法是,通过如下更改您的 DataBindings 类:

 public class DataBindings : NinjectModule 
    { 
        public override void Load() 
        { 
            Bind<IReviewRepository>().To<ReviewRepository>(); 
            Bind<ReviewManager>().ToSelf();
        }  
    } 

在您的调用者中,不要

var rm = new ReviewManager();

尝试使用

var rm = ServiceLocator.Kernel.Get<ReviewManager>();

我还没有测试过此代码,但我认为它会解决您的空引用问题。

A potential workaround, by changing your DataBindings class as follows:

 public class DataBindings : NinjectModule 
    { 
        public override void Load() 
        { 
            Bind<IReviewRepository>().To<ReviewRepository>(); 
            Bind<ReviewManager>().ToSelf();
        }  
    } 

And within your caller, instead of

var rm = new ReviewManager();

Try using

var rm = ServiceLocator.Kernel.Get<ReviewManager>();

I havent tested this code, but i think it'll solve your null reference problem.

岁月打碎记忆 2024-12-12 12:01:03

我对页面、母版页和用户控件使用属性注入。例如,我的所有页面都继承自一个基类,该基类使用以下代码覆盖 RequestActivation 方法:

    ''' <summary>
    ''' Asks the kernel to inject this instance.
    ''' </summary>
    Protected Overridable Sub RequestActivation()
        ServiceLocator.Kernel.Inject(Me)
    End Sub

并且在每个页面中我声明可注入属性:

    <Inject()>
    Property repo As IMyRepository

I use property injection for pages, masterpages and usercontrols. All my pages, for example, inherit from a base class that overrides RequestActivation method with the following code:

    ''' <summary>
    ''' Asks the kernel to inject this instance.
    ''' </summary>
    Protected Overridable Sub RequestActivation()
        ServiceLocator.Kernel.Inject(Me)
    End Sub

And in each page I declare injectable properties:

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