Copied to clipboard

Flag this post as spam?

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


  • Allan Svelmøe Hansen 25 posts 136 karma points
    Jul 16, 2019 @ 13:15
    Allan Svelmøe Hansen
    0

    Dependency Injection and Published Content + Culture change (v.8.1)

    I'm wondering what the correct / ideal approach would be to use Dependency Injection (DI) now for published content with culture, and especially children change in v8.1

    There are a few issues/questions so I hope I explain myself proper and will try to keep it as simple / focused as possible :)

    Suppose: I have a custom content service being build using (amongst other things) published content, and I want it to be DI and also minimize logic in the view itself (for example via viewmodels/display templates etc).

    This means that the razor helper Umbraco is not available because content will be accessed in a code file, not a razor view.

    So I've found a few methods of accessing content, but I'm unsure which is preferred

    It seems possible to inject UmbracoHelper directly into my custom class. This however often seem to run into an isuse where the snapshot is disposed and I suspect it might suffer a bit from the 'singleton' issue of v.7.x?

    Via another similar thread I found IUmbracoContextFactory and can access content via

    private readonly IUmbracoContextFactory _umbracoContextFactory;
    public MyClass(IUmbracoContextFactory umbracoContextFactory)
    {
      _umbracoContextFactory = umbracoContextFactory;
    }     
    

    and

    using (var contextFactory = _umbracoContextFactory.EnsureUmbracoContext())
        {
             var content = _umbracoContextFactory.UmbracoContext.Content.GetAtRoot().OfType<MyType>()?.FirstOrDefault();
        }
    

    But the e.g. document.Children(culture) is always empty whereas CultureForAllDomains is populated. But as I understand it, I would then need to manually check if content is available for my given culture? Or is the content now filtered by culture?

    I also saw the IPublishedContentQuery which does seem to work similar to the IUmbracoContextFactory, but the IPublishedContentQuery seems to be inside the UmbracoHelper so I suspect it has the same 'snapshot' issues.

    Or is there another and/or simpler way I'm overlooking?

  • Marc Goodson 2141 posts 14324 karma points MVP 8x c-trib
    Jul 21, 2019 @ 10:41
    Marc Goodson
    1

    Hi Allan

    There are some examples of DI that are 'work in progress' in the Umbraco Docs, that might be worth a read through, the most recent version is available here:

    https://github.com/umbraco/UmbracoDocs/blob/512a77c26eaed3e238955a56411d6ba3d0d28b00/Implementation/Services/index.md

    Essentially it depends 'a lot' on where your custom C# class will be used...

    ... if you are ONLY using it from a Controller or View, then you can register your custom c# class in 'Lifetime.Request' scope, and it will be 'safe' to inject the familar IPublishedTypedQuery into the constructor of your custom class to work with the published cache in the same way as you would via UmbracoHelper....

    but if you subsequently try to use your custom c# class outside of a HttpRequest eg in a Component/handling an event - then you'll get a boot error on startup...

    So if you need your c# class to be called outside of a HttpRequest, then that's when you use the UmbracoContextFactory approach to access the ContentCache... and since this approach works in both scenarios... then although it's a little more involved, means you won't get caught out if you need to use your custom class outside a HttpRequest in the future...

    In terms of what is returned by the .Children(string culture = null) extension method on an IPublishedContent item:

    https://github.com/umbraco/Umbraco-CMS/blob/3bfd9b71e290354744d677440983ecd06c5c0788/src/Umbraco.Core/PublishedContentExtensions.cs#L103

    the logic appears to be if no culture is passed to the method, to use the culture of the current thread in the filtering...

    https://github.com/umbraco/Umbraco-CMS/blob/853087a75044b814df458457dc9a1f778cc89749/src/Umbraco.Core/Models/PublishedContent/ThreadCultureVariationContextAccessor.cs

    Now on the front end of the site, in a view or controller, this should be the culture of the variation the site visitor is requesting, but if your custom code is actioned in a Component or Event, then that default thread culture might be a culture that isn't used on your Umbraco content tree , eg en-US, and so you get no children...

    ... I am guessing from the source implementation!

    Anyway once you have an IPublishedContent item from either of the approaches, Children("en-GB") should return all the UK children variants etc

    But it's also possible since this is new in the release of 8.1 that there is a bug...

    It would be interesting to see if .Children("*") all children, and whether this contains children with the culture you are seeking which are not returned when you specify the culture...

    Anyway, hope this is information of help, even if it perhaps isn't the exact answer to your question!

    regards

    Marc

  • Marc Goodson 2141 posts 14324 karma points MVP 8x c-trib
    Jul 22, 2019 @ 13:20
    Marc Goodson
    0

    Also noticed this issue on the issue tracker:

    https://github.com/umbraco/Umbraco-CMS/pull/5946

Please Sign in or register to post replies

Write your reply to:

Draft