Copied to clipboard

Flag this post as spam?

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


  • Malthe Petersen 6 posts 77 karma points
    Mar 08, 2019 @ 07:46
    Malthe Petersen
    0

    Custom application started events

    Hi.

    I have an application running on Umbraco 7.11, but I need to upgrade it to Umbraco 8 - awesome!

    The thing is in Umbraco 7.* you have the possibility to hook events to the ApplicationInitialized/ApplicationStarting/ApplicationStarted from ApplicationEventHandler, but now that is gone.

    Is there an equivalent in Umbraco 8?

    Best regards Malthe

  • Sebastiaan Janssen 4811 posts 14059 karma points MVP admin hq
    Mar 08, 2019 @ 07:49
  • Malthe Petersen 6 posts 77 karma points
    Mar 08, 2019 @ 07:52
    Malthe Petersen
    0

    Hi Sebastian.

    Thank you very much. I will look into the IRuntimeComposer and ICoreComposer.

  • Malthe Petersen 6 posts 77 karma points
    Mar 08, 2019 @ 07:58
    Malthe Petersen
    0

    One more thing:

    In Umbraco 7.* we have the ApplicationContext, but I can't seem to find it in Umbraco 8.

    Is it gone? and if yes, is there any equivalent?

  • Sebastiaan Janssen 4811 posts 14059 karma points MVP admin hq
    Mar 08, 2019 @ 09:18
    Sebastiaan Janssen
    3

    It depends a bit on what you need from the "ApplicationContext". I assume you're looking for some Services, in which case you can use dependency injection to get the Service you need, for example:

    public class MyComponent : IComponent
    {
        private readonly IContentService _contentService;
    
        public MyComponent(IContentService contentService)
        {
            _contentService = contentService;
        }
        public void Initialize()
        {
            var contentAtRoot = _contentService.GetRootContent().FirstOrDefault();
            if (contentAtRoot != null)
            {
                var name = contentAtRoot.Name;
                // etc.
            }
        }
    
        public void Terminate()
        {
        }
    }
    

    We should document the most common things to access.

    If you're not familiar with dependency injection then you can do some reading about "dependency injection through contructor injection" - which is a widely used pattern. If you don't care then all you need to know is that bit of code:

        public IContentService _contentService { get; }
    
        public MyComponent(IContentService contentService)
        {
            _contentService = contentService;
        }
    

    The constructor of this class ask for an IContentService using public MyComponent(IContentService contentService) and you make it available to the whole class through the _contentService property, so you can use it in all of your methods.

    Discovering what's available for you to use (also known as "cheating")

    Note: we do NOT encourage it, but you can cheat a little bit, when you do using Current = Umbraco.Web.Composing.Current; you can type Current. your code to see everything that's available to you, which is also (and preferably) available using dependency injection:

    enter image description here

    This also allows you to discover what you can ask for from dependency injection, so to figure out how to get a ContentService, you go Current.Services.ContentService and Visual Studio will show you that you need to ask for an IContentService:

    enter image description here

    And that's what I did in my constructor:

        public IContentService _contentService { get; }
    
        public MyComponent(IContentService contentService)
        {
            _contentService = contentService;
        }
    

    Using Current is "cheating" and a bit of an anti-pattern, try to avoid it as much as you can. Once you get used to dependency injection, I'm sure you'll start to appreciate it. 😁

  • Paul Seal from codeshare.co.uk 347 posts 1820 karma points MVP c-trib
    Mar 08, 2019 @ 13:45
    Paul Seal from codeshare.co.uk
    0

    Great answer Seb,

    So if we are ever tempted to use Current. to get a service, we should always use DI to pass it into the constructor? Cool.

  • Sebastiaan Janssen 4811 posts 14059 karma points MVP admin hq
    Mar 08, 2019 @ 14:53
    Sebastiaan Janssen
    0

    Sometimes it's impossible to do constructor injection, so.. it depends. Try very hard to make it work though.

    Some more reading can be done in Shannon's UDUF slides: https://shazwazza.com/media/1032/uduf-2019.pdf

  • Malthe Petersen 6 posts 77 karma points
    Mar 11, 2019 @ 08:40
    Malthe Petersen
    0

    Thank you for the answer. Pretty awesome :-)

  • Tony H 52 posts 69 karma points
    Mar 14, 2019 @ 13:44
    Tony H
    0

    I'm trying to the UmbracoHelper to work in my IComponent to be able to get an page via Guid.

    I Would like to use something like: Umbraco.Content(guid);

    But I don't seem to be able to get the UmbracoHelper via dependency injection.

    I do get the IUmbracoContextFactory which will give me the ContentCache but the ContentCache doesn't seem to support getting content by "guid" just "Id".

    At the moment I'm using the Constructor:

     public CustomExamineComponent(IExamineManager examineManager, CustomIndexCreator indexCreator, IContentService contentService, IUmbracoContextFactory umbracoContextFactory)
        {
            _examineManager = examineManager;
            _indexCreator = indexCreator;
            _contentService = contentService;
            _umbracoContextFactory = umbracoContextFactory;
        }
    

    What am I missing?

  • Sebastiaan Janssen 4811 posts 14059 karma points MVP admin hq
    Mar 14, 2019 @ 13:55
    Sebastiaan Janssen
    0

    It definitely should allow you to query by Guid:

    enter image description here

    An example:

    public class MyComponent : IComponent
    {
        private readonly IUmbracoContextFactory _context;
    
        public MyComponent(IUmbracoContextFactory context)
        {
            _context = context;
        }
    
        public void Initialize()
        {
            using (var cref = _context.EnsureUmbracoContext())
            {
                var cache = cref.UmbracoContext.ContentCache;
                GuidUdi udi = null; /// wherever this is coming from
                var node = cache.GetById(udi.Guid);
            }
            ...etc
    

    Make sure to use that using block to Ensure that the UmbracoContext is available! 👍

  • David Zweben 202 posts 566 karma points
    Apr 12, 2019 @ 20:15
    David Zweben
    0

    Thanks. Is there any harm in making cache another private readonly class member like _context, and moving the using block into the class' constructor? The idea being to make the cache accessible throughout the whole class.

Please Sign in or register to post replies

Write your reply to:

Draft