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.
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:
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:
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. 😁
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".
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! 👍
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.
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
Here's an example of how to hook up events: https://our.umbraco.com/documentation/Implementation/Composing/#example---creating-a-component-to-listen-for-contentservicesaving-events
Hi Sebastian.
Thank you very much. I will look into the IRuntimeComposer and ICoreComposer.
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?
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:
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:
The constructor of this class ask for an
IContentService
usingpublic 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 typeCurrent.
your code to see everything that's available to you, which is also (and preferably) available using dependency injection: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 anIContentService
:And that's what I did in my constructor:
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. 😁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.
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
Thank you for the answer. Pretty awesome :-)
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:
What am I missing?
It definitely should allow you to query by Guid:
An example:
Make sure to use that using block to Ensure that the UmbracoContext is available! 👍
Thanks. Is there any harm in making
cache
anotherprivate readonly
class member like_context
, and moving theusing
block into the class' constructor? The idea being to make the cache accessible throughout the whole class.is working on a reply...