Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Javz 38 posts 141 karma points
    May 18, 2020 @ 22:28
    Javz
    0

    Registering UmbracoHelper in DI

    Hi all,

    In V7 of Umbraco, registering UmbracoHelper was as simple as the following:

    builder.Register(x => new UmbracoHelperWrapper(new UmbracoHelper(UmbracoContext.Current))).As

    However, in V8 (specifically 8.5.5), it appears that there are several parameters that need to be passed on in order to set this up.

    I can't seem to find any documentation on this, and the above method seems too complex for something that was so simple?

    Any help is appreciated.

    Thanks

  • Anders Bjerner 487 posts 2989 karma points MVP 7x admin c-trib
    May 19, 2020 @ 07:38
    Anders Bjerner
    0

    Hi Javz,

    May I ask what you're using the UmbracoHelper class for? Essentially it's a wrapper class for accessing other parts of Umbraco. So it may be more ideal to reference those parts via DI instead when and where you need them.

    Personally I haven't used UmbracoHelper outside of views or controllers yet in Umbraco 8, so not sure how you'd register one via DI. But I'm wondering what type your builder variable is? Maybe you can share a bit more of your code where you're registering your wrapper?

  • Javz 38 posts 141 karma points
    May 19, 2020 @ 12:56
    Javz
    0

    Hi Anders,

    Currently I am trying to get the current page via the macro and pass it to the service class, I did create another thread explaining that - https://our.umbraco.com/forum/using-umbraco-and-getting-started/102172-get-current-page-via-a-macro and it was later discovered that DI was not set up properly for UmbracoHelper

    I'm generally wrapping up the UmbracoHelper class to minimise numerous direct calls to Umbraco. Currently I have the following in the custom wrapper class:

    public class UmbracoHelperWrapper : IUmbracoHelper
    {
        private readonly UmbracoHelper _umbracoHelper;
    
        public UmbracoHelperWrapper(UmbracoHelper umbracoHelper)
        {
            _umbracoHelper = umbracoHelper ?? throw new ArgumentNullException(nameof(umbracoHelper));
        }
    
        public IPublishedContent GetCurrentPage()
        {
            return _umbracoHelper.AssignedContentItem;
        }
    
        public IPublishedContent TypedContent(Guid id)
        {
            return _umbracoHelper.Content(id);
        }
    
        public IPublishedContent TypedContentSingleAtXPath(string path)
        {
            return _umbracoHelper.ContentSingleAtXPath(path);
        }
    
        public IEnumerable<IPublishedContent> TypedContentAtXPath(string path)
        {
            return _umbracoHelper.ContentAtXPath(path);
        }
    }
    

    And I registered this class in V8 as:

    composition.Register<IUmbracoHelper, UmbracoHelperWrapper>();
    

    However, UmbracoHelper is not populated. In V7 it was done in in DI as:

    builder.Register(x => new UmbracoHelperWrapper(new UmbracoHelper(UmbracoContext.Current))).As<IUmbracoHelper>().InstancePerRequest();
    

    The builder is of the ContainerBuilder type, which is part of AutoFac, but given V8 is DI out of the box, I don't think its no longer necessary to use that.

  • Marc Goodson 2141 posts 14344 karma points MVP 8x c-trib
    May 19, 2020 @ 08:27
    Marc Goodson
    0

    Hi Javz

    There is some documentation here about when you would and wouldn't access UmbracoHelper inside Views/Controllers/Components:

    https://our.umbraco.com/documentation/Implementation/Services/

    It's a long read...

    but in short if you need to access the Umbraco Published Cache outside of a request, you'll need to use IUmbracoContextFactory

    If you want the syntax sugar of UmbracoHelper, then you'll need to register your custom code class in 'request scope' to be able to inject that and get reference to the AssignedContentItem

    regards

    Marc

  • Javz 38 posts 141 karma points
    May 19, 2020 @ 13:22
    Javz
    0

    Hi Marc,

    I don't believe it's possible to get the current page (AssignedContentItem) via the IUmbracoContextFactory? As that seems to be part of the UmbracoHelper.

    I have done the following, is that what you want meant:

    composition.Register<IUmbracoHelper, UmbracoHelperWrapper>(Lifetime.Request);
    

    However, I don't think this is correctly registered

  • Anders Bjerner 487 posts 2989 karma points MVP 7x admin c-trib
    May 19, 2020 @ 13:43
    Anders Bjerner
    0

    UmbracoContext gives you access to the current Umbraco request, so you should be able to access the current page via:

    factory.EnsureUmbracoContext().UmbracoContext.PublishedRequest.PublishedContent
    

    You may need to add some null checks along the way, but otherwise it should do the trick ;)

  • Javz 38 posts 141 karma points
    May 19, 2020 @ 14:11
    Javz
    0

    Thanks Anders! However, I am getting a null.

    To give more context, I am trying to get the current page whenever a macro is being used on a page. i.e. If there is an About page, the macro will then be called and then the About page would be returned, irregardless whether the page is published or not. And, in V7, I found that the surefire way was to use the UmbracoHelper.

    Again, thanks for your help! It's much appreciated!

  • Javz 38 posts 141 karma points
    May 19, 2020 @ 16:51
    Javz
    0

    Ironically, I can get the HttpContext, and that does return the macro, but whenever trying to get current page via the above, it provides a null.

    Of course, you can use GetById, but that is not what I want to do, as I want to get the page dynamically.

  • Anders Bjerner 487 posts 2989 karma points MVP 7x admin c-trib
    May 19, 2020 @ 19:46
    Anders Bjerner
    0

    Just a quick thought. If we're talking about a macro partial view, what class is your view inheriting from?

    If you create a new macro partial view through the backoffice, you'll get a Razor view that inherits from PartialViewMacroPage. If this is the case, you should be able to get the current page through Model.Content - eg. as shown here:

    @inherits Umbraco.Web.Macros.PartialViewMacroPage
    
    @{
    
        <h3>This is a macro</h3>
    
        <pre>@Model.Content.Name</pre>
    
    }
    

    I just tested this, and it also works during preview (eg. unpublished content). It also works for the preview in the backoffice if you have enabled Render in rich text editor and the grid for your macro.

    Does this work for you?

    If it doesn't, there may be an underlying issue - which also could explain why you're getting null through the approach with the factory.

  • Javz 38 posts 141 karma points
    May 19, 2020 @ 20:47
    Javz
    0

    Hi Anders,

    Yes, the macro is inheriting the PartialViewMacroPage and I initially was using the Model from within this razor and then passing that as a parameter to get the current page, which does work for both published/unpublished instances.

    However, I am lead to believe this may be bad practice to pass models when trying to get the current page dynamically. However, this raises questions as to why the factory would be null?

Please Sign in or register to post replies

Write your reply to:

Draft