1

I'm trying (and failing) to get property injection working in Orchard CMS.

This is necessary, because the below code is acting something like a code-behind for a view (horrible I know). The reason being that the view doesn't have a controller that I can use constructor injection on, because this is an alternate view for a MenuItem, i.e. MenuItemLink-MyCustomMenuItem.cshtml.

Not much more to say than that, except what's in the comments (note the NULL comment for the property that I am trying to set in the code below).

Oh, I've also tried adapting the property injection code from Orchard's LoggingModule, but equally that doesn't work for me either.

How do I :

a. get the below property injection to work? (I'm pretty sure I will need it at some point regardless)

b. (if possible) get my own controller/driver in the way of the view so I can use constructor injection on the controller instead?

using System.Diagnostics;
using System.Xml.Linq;
using Autofac;
using Autofac.Core;
using Orchard;
using Module = Autofac.Module;

namespace MyCo.MyCustomMenuItem.Services 
{

    public class MyCustomMenuItemModule : Module 
    {

        protected override void AttachToComponentRegistration(
            IComponentRegistry componentRegistry, 
            IComponentRegistration registration)
        {
            if (implementationType.ToString() == 
                        "MyCo.MyCustomMenuItem.Services.MyCustomMenuItem") 
            {
                // this does get called, but doesn't have the desired effect
                registration.Activated += (s, e) => 
                         e.Context.InjectUnsetProperties(e);
            }
        }

    }

    public interface IFeedX : IDependency 
    {
        XDocument GetResource();
    }

    public class FeedX : IFeedX
    {
        public XDocument GetResource() 
        {
            return new XDocument();
        }
    }

    public interface IMyCustomMenuItem : IDependency 
    {
        XDocument GetResourceData();

        IFeedX FeedX { get; set; }
    }   

    public class MyCustomMenuItem : IMyCustomMenuItem
    {
        public IFeedX FeedX { get; set; }

        // called direct by razor view
        public XDocument GetResourceData()
        {
            Debug.WriteLine(FeedX); // NULL??

            return FeedX.GetResource(); 
        }

    }

}
jimasp
  • 962
  • 9
  • 26
  • Links to property injection in Orchard, for anyone interested: (1) http://www.szmyd.com.pl/blog/di-property-injection-in-orchard and also (2) http://whereslou.com/2009/10/25/injecting-an-ilogger-property-with-autofac – jimasp Feb 22 '13 at 08:42

1 Answers1

1

You definitely should not do anything of the sort in the view. I think this article describes a scenario that is close to what you're trying to achieve: http://www.davidhayden.me/blog/dynamically-injecting-menu-items-in-orchard-cms

Bertrand Le Roy
  • 17,731
  • 2
  • 27
  • 33
  • Thanks, I'll certainly have a look at that this weekend and see if it does what I need. Any idea why the property injection doesn't work btw (given that the attach method gets called)? – jimasp Feb 07 '13 at 09:44
  • Orchard relies on constructor injection. Property injection only works for very few things such as Localizer, and I'm not even sure what the constraints are on those. In any case, you don't have a good reason to do it in this scenario. – Bertrand Le Roy Feb 07 '13 at 18:47
  • Ok, I had a look at the code in the link that you provided, but that simply injects some text into a menu item, i.e. MenuItem.Text = new LocalizedString(tag.TagName). Whereas I want to supply completely custom html for the menu item via a view (or partial) which is dynamically populated from an external source. Currently, the only way I can find to do this is by an alternate view and a code-behind. – jimasp Feb 10 '13 at 11:32
  • (Using the example you linked, I could generate my html in code, and inject it, but the html is non-trivial, so I want to use a view for maintainability). – jimasp Feb 10 '13 at 11:51
  • Look at the HtmlMenuItem content type: it has the menu part, the body part, the common part, the identity part and has the stereotype `MenuItem`. This should make it clear that menu items are just content types with the menu item stereotype, and so you can build completely arbitrary item types and add your own custom parts. There is absolutely no need for code-behind or dirty hacks in views. – Bertrand Le Roy Feb 10 '13 at 20:22
  • Thank you, your last comment made sense to me, and I was able to figure it out from that. – jimasp Feb 22 '13 at 08:39