0

I have a partial (user control) that shows a menu of links. It lives on my masterpage. If you are an admin, you should see a different menu from others.

I have a method in my Member class called: IsAdmin(). Normally it would be very easy to just put some logic in the partial declaratively to show the right menu if someone is an admin, such as:

<% if (member.IsAdmin()) { %>

But since I am using Ninject for dependency injection and my Member class cannot be instantiated without the required dependencies (an IMemberRepository) I am not sure how to do this in my partial. I know that Ninject can supply a the repository to my Controller class' constructor, but I do not knowhow to do this in a partial.

tereško
  • 58,060
  • 25
  • 98
  • 150
Joe
  • 734
  • 1
  • 8
  • 14

3 Answers3

2

In my opinion view injection should not be used at all because it is hardly testable by unit tests. Consider to change the design and let the controller change the view model instead and use the view model to decide what is shown.

If you really want to do view injection there is an example in the MVC3 sample application: https://github.com/ninject/ninject.web.mvc/tree/master/mvc3/src/SampleApplication/Views/Math

Remo Gloor
  • 32,665
  • 4
  • 68
  • 98
0

I figured it out. In my partial I put the following in:

IKernel kernel = new StandardKernel(new NinjectControllerFactory.MyServices());
MembershipService membershipService = new MembershipService(kernel.Get<IMemberRepository>());

And now I can do the following:

if (Request.IsAuthenticated && membershipService.IsAdmin()) 
{
Joe
  • 734
  • 1
  • 8
  • 14
  • 2
    This is far from a good solution. Just a very ugly hack and a good example how not to use Ninject. – Remo Gloor Apr 13 '11 at 20:57
  • 1
    @Remo Gloor it would probably be useful then if you could tell us how to do it without using an "ugly hack". – Joe Apr 14 '11 at 17:25
  • I posted an answer long ago telling how to do it. It is exactly the same answer as Baldy's. Don't use dependency injection on views let your controller do the decission by changing the view model. – Remo Gloor Apr 14 '11 at 17:32
0

I was in this same predicament last week, as i have a partial that provides a list of 'top locations' to various views.

Ensure that the controller is injected with the necessary service or repository to provide the partial with the data it requires, then pass it to the view as a dynamic viewdata property (in mvc3)...

       public class LocationController : Controller
    {
        private readonly ILocationService _svc;

        public LocationController(LocationService svc)
        {
                _svc = svc;
        }

        public ActionResult Index()
        {
            //get data for 'top locations' partial
            var topOnes = svc.GetTopLocations(10);
            ViewData.TopLocations = topOnes;
            //mvc2 would be ViewData["TopLocations"] = topOnes;

            //get 'main' view data
            var location  = svc.GetDefaultLocation();
            return View(location);
        }

Or, more formally, include it in the view model that your controller returns.

Baldy
  • 3,621
  • 4
  • 38
  • 60
  • That would work except this partial exists on my master page. However I did fail to mention that...So I will award you the points. But do please let me know how you think you would do it if the partial was on the master page (if it would differ from my solution below). – Joe Apr 14 '11 at 17:24
  • if the partial was going in my master page, the first thing i would consider is whether it will actually be used anywhere else (like another master page, or page that doesnt use the master) - if the answer is no, then i would move its content to the master page. there are a few approaches to how you would supply the master page with the data which are covered here... http://stackoverflow.com/questions/78548/passing-data-to-master-page-in-asp-net-mvc – Baldy Apr 17 '11 at 14:39