views:

69

answers:

2

First off, I'm using Ninject 2.0

I have my master page which I would like to inject into but I'm not quite sure how. What I tried was created a class that derives from System.Web.Mvc.ViewMasterPage and then I create my properties:

[Inject]
public ICacheService<List<Category>> Categories { get; set; }
[Inject]
public IConfigurationSettings Config { get; set; }

When I run my page neither of the properties get set and are both null. Any ideas on why or example on how to do this? Thanks

-- Update

So I've done more research and it seems I need to resolve the objects within the class myself because Ninject does not intercept the creation of the class. So now my question is how do I create a resolver for my kernel? The above code is within a class library so I don't have a reference to the kernel. I tried the following: (slightly modified from http://www.codethinked.com/post/2009/10/07/Our-Biggest-Enemy-Isne28099t-Developers-Who-Refuse-To-Move-Forward-It-is-Developers-Who-Pretend-To-Move-Forward.aspx )

public class KernelResolver
{
    private static IKernel _kernel;

    public KernelResolver(IKernel kernel)
    {
        _kernel = kernel;
    }

    public static T Resolve<T>()
    {
        return _kernel.Get<T>();
    }
}

and then registered:

Bind<KernelResolver>().ToSelf()

Yet kernel is null... I just need to see some examples but I can't find any or it could be that I'm so confused that I don't know what I'm looking for :\

Any help is much appreciated!

+1  A: 

The KernelResolver class implements a service locator pattern (asking something [central] for your dependencies), which is generally more a last resort than a primary approach. What you really want is to get your dependency injection working.

You definitely dont Bind KernelResolver to anything - it acts as the overall container, and the system (e.g., MVC's factories) need to be hooked up to get it to help out.

The [Inject] attributes don't do anything magic on their own - they're used by Ninject when someone requests it to inject an object of that type.

What you're looking for is an example of how you tell MVC to call Ninject at the right times, which I'll let you search for (ninject "asp.net mvc" example?).

Ruben Bartelink
+2  A: 

I'll start by asking: why do you want to inject anything into a master page? If you are using MVC, you really want to use models to pass data to your views (including the master page) by way of a controller. That's the essence of an MVC framework, if perhaps over-simplified.

What Ninject or other IoC containers can do for you is help create your controller classes and inject dependencies into them -- indeed the integration point for IoC containers in ASP.Net is typically taking over the responsibility of the controller factory.

Injecting appropriate dependencies into your controller may assist the controller in determining the appropriate model or state of the model to pass to your views (including the master page).

I like to think of the MVC pattern (and, for that matter, ASP.Net MVC) as placing the responsibility of all the decision making (i.e. control) in the controller classes. The decisions carried out by controllers may be shaped by numerous inputs (e.g. configuration, user input, environment, etc) but at some point, a model is passed to a view by the controller. I think of the model containing the state of the subject matter of the system. The views, in my opinion, especially in ASP.Net MVC are best viewed as being void of any logic and more like "scripts" than true classes or first-class cititzens in some object model.

Perhaps you have a valid reason for making your view master page "smarter", but typically, the types of things you're looking to inject are best injected to your controller and the requisite data passed to your view. I'd be curious to hear more about what you're trying to accomplish.

Note: you can easily setup Ninject integration with MVC to have all your controllers' dependencies injected. Check out this StackOverflow question/answer thread for the details.

Peter Meyer
"the integration point for IoC containers in ASP.Net is typically taking over the responsibility of the controller factory."-- That clears things up immensely. What I was trying to accomplish was having my config settings available to all pages, including the master page, automatically without being passed in via the controller. So I guess I just need to pass all my dependencies to my model via the controller. I imagine it like a tree, the controller at the top and injection flows downward as necessary.
DennyDotNet
And to clarify, my original idea was that DI was like a checkpoint and any instantiation in the app would run through this "checkpoint" at which point the object would be inspected and injected to as necessary.
DennyDotNet
I think viewing the controller at the "top" with things flowing down is a good way of visualizing the flow. Now I understand what you were trying to do, which really is quite logical. You may want to think about what kind of config settings you're trying to share among all pages and how those settings change the behavior (or otherwise) of the application. Perhaps it can be applied to the model?
Peter Meyer