Copied to clipboard

Flag this post as spam?

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


  • Ismail Mayat 4511 posts 10090 karma points MVP 2x admin c-trib
    Oct 02, 2019 @ 10:15
    Ismail Mayat
    0

    Composer does not have parameterless constructor

    I have getting the following error when composing:

    Composer Site.Core.Composers.TagComposition does not have a parameter-less constructor.

    The code looks like:

        [RuntimeLevel(MinLevel = RuntimeLevel.Run)]
    [ComposeAfter(typeof(BaseCompositions))]
    public class TagComposition:IUserComposer
    {
        private readonly ITagService _tagService;
    
        public TagComposition(ITagService tagService)
        {
            _tagService = tagService;
        }
    

    I need to inject in that tagservice which was registered in BaseCompositions : I am doing it wrong I guess. Bascially in this composer I am trying todo:

            public void Compose(Composition composition)
        {
            ExamineManager.Instance.TryGetIndex(HiqhQIndexConstants.ExamineIndexName, out var highQIndex);
    
            highQIndex.IndexOperationComplete += HighIndexingComplete;
        }
    

    In the HighIndexingComplete method I use tag service.

    What is the correct way todo this?

  • Nik 1593 posts 7151 karma points MVP 6x c-trib
    Oct 02, 2019 @ 10:20
    Nik
    0

    Hey Ismail,

    I don't think Composers can have things injected into them. This is why we use Components and the Composer is there to register the component.

    If you look at my post here: https://www.justnik.me/blog/indexing-sort-able-dates-in-umbraco-version-8 I'm interacting with indexing events, granted not the same event you are, but if you do it within a Component you can use DI to get the services etc you need :-)

    Thanks

    Nik

  • Ismail Mayat 4511 posts 10090 karma points MVP 2x admin c-trib
    Oct 02, 2019 @ 11:06
    Ismail Mayat
    0

    So I have updated things but now get

    Boot failed: Umbraco cannot run. See Umbraco's log file for more details.

    -> Umbraco.Core.Exceptions.BootFailedException: Boot failed.

    -> System.NullReferenceException: Object reference not set to an instance of an object. at Umbraco.Web.Runtime.WebInitialComposer.<>c.

    I have

        [RuntimeLevel(MinLevel = RuntimeLevel.Run)]
    public class BaseCompositions : IUserComposer
    {
        public void Compose(Composition composition)
        {
            RegisterServices(composition);
    
            RegisterComponents(composition);
        }
    

    in register services i register my tag service. I then register component:

            private void RegisterComponents(Composition composition)
        {
            composition.Components().Append<HighQTagComponent>();
        }
    

    and that component looks like:

        public class HighQTagComponent:IComponent
    {
        private readonly ITagService _tagService;
    
        public HighQTagComponent(ITagService tagService)
        {
            _tagService = tagService;
        }
    

    Still missing something I think?

  • Ismail Mayat 4511 posts 10090 karma points MVP 2x admin c-trib
    Oct 02, 2019 @ 11:45
    Ismail Mayat
    0

    So playing with this a bit more:

    My tagservice has constructor:

            public HighQTagService(ITagRepository tagRepository,ITagQuery tagQuery)
        {
            _tagRepository = tagRepository;
            _tagQuery = tagQuery;
        }
    

    The 2 items i am injecting in belong in:

    using Umbraco.Core.Persistence.Repositories;
    

    using Umbraco.Web;

    when i take those out the constructor everything boots up. I took out ITagQuery and it boots. Looks like it does not like me injecting ITagQuery in.

    Anyone any ideas?

    Regards

    Ismail

  • Dave Woestenborghs 3504 posts 12133 karma points MVP 8x admin c-trib
    Oct 02, 2019 @ 12:24
    Dave Woestenborghs
    0

    Hi Ismail.

    ITagRepository and ITagQuery are Umbraco core things, right ?

    Maybe core is not set up to use them in DI ?

    Edit : Can you try to inject them in a controller just to check ?

    Dave

  • Ismail Mayat 4511 posts 10090 karma points MVP 2x admin c-trib
    Oct 02, 2019 @ 12:37
    Ismail Mayat
    0

    according to this it should work https://our.umbraco.com/Documentation/Reference/Cache/examples/tags

    the ITagQuery one is the problem the repo one injects fine.

  • Nik 1593 posts 7151 karma points MVP 6x c-trib
    Oct 02, 2019 @ 12:26
    Nik
    0

    @Dave: ITagQuery is set up as DI https://github.com/umbraco/Umbraco-CMS/blob/8b7418164d112e7247e901f18c486ff37e1fa611/src/Umbraco.Web/Runtime/WebInitialComposer.cs#L104

    It's also injected in the UmbracoHelper class in core.

    @Ismail, how are you registering your service? I'm wondering if it's throwing an issue because ITagQuery is registered as having a lifetime of Request

    Nik

  • Nik 1593 posts 7151 karma points MVP 6x c-trib
    Oct 02, 2019 @ 12:27
    Nik
    0

    Also, does it work if you remove:

    [RuntimeLevel(MinLevel = RuntimeLevel.Run)]
    

    Nik

  • Ismail Mayat 4511 posts 10090 karma points MVP 2x admin c-trib
    Oct 02, 2019 @ 12:36
    Ismail Mayat
    0

    Nik,

    I was registering as singleton changed it to request still no joy. I also removed Runtime level attribute still no joy.

  • Nik 1593 posts 7151 karma points MVP 6x c-trib
    Oct 02, 2019 @ 13:00
    Nik
    0

    It might be that you can't use the ITagQuery within a component, Umbraco is at too low a level when this is working, and so the web request bits that it relies on aren't established (just a guess) but it works if you are injecting the services into a controller but not if you are injecting the service into a component constructor.

  • Kevin Jump 2311 posts 14697 karma points MVP 7x c-trib
    Oct 02, 2019 @ 13:42
    Kevin Jump
    0

    HI

    I think it might be because it's circular.?

    The core TagQuery class constructor requires ITagService.

    public TagQuery(ITagService tagService, IPublishedContentQuery contentQuery, UmbracoMapper mapper)
    

    So when it tries to resolve the ITagService for TagQuery in the service it can't because the service isn't there.

    I think if you want to implement your own ITagService you can't use ITagQuery within it.

    The core ITagService goes to the DB for all of it's tags, maybe you could inherit that as a base class and intercept the bit you need?

    UPDATE: No It might be a bit more complicated that that :( - I can't get it to register in any service

  • Kevin Jump 2311 posts 14697 karma points MVP 7x c-trib
    Oct 02, 2019 @ 13:59
    Kevin Jump
    0

    I think you can only use the ITagQuery within a request.

    so if you register your service to havea lifetime of request

    public class MyTagService
    {
        public MyTagService(ITagQuery tagQuery)
        {
    
        }
    }
    

    composed :

    composition.Register<MyTagService>(Lifetime.Request);
    

    then this will register and can be injected into a controller for example but if you try to use the service in a component it will blow up.

    I think this is because ITagQuery has a lifetime of Request, and requires IPublishedContentQuery which i think reliies on an Umbraco Context which you don't have during the startup in a component.

  • Ismail Mayat 4511 posts 10090 karma points MVP 2x admin c-trib
    Oct 02, 2019 @ 14:08
    Ismail Mayat
    0

    Cool,

    Makes sense although while on the bog i just figured out the method i need in that service calls a method on the IRepo which i can inject so i can just use that lol.

    Many thanks for your help guys.

  • Kevin Jump 2311 posts 14697 karma points MVP 7x c-trib
    Oct 02, 2019 @ 14:12
    Kevin Jump
    0

    lol but TMI :)

Please Sign in or register to post replies

Write your reply to:

Draft