开发者

Ninject + ASP.NET Web Forms Not Working

开发者 https://www.devze.com 2023-04-06 10:54 出处:网络
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

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>();
开发者_Python百科        }
    }

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


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).


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.


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.


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
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号