Can't get two ISearchableTree implementations to work at the same time
I'm toying around in Umbraco Backoffice with making the search function return extra results, dependent on tags put on documents or media.
They both work, separatly, but if I compose in both of them, everything breaks. Doesn't matter which one. I am probably missing something very simple.
I have made two ISearchableTree implementations looking like this:
For content search and
For media search.
This is my "TagSearcher" by the way
As said, when only one (lets say I comment out the compose part in the AddMediaSearchExtender) is enabled, they perform as expected. If both are enabled, I get this error:
Any ideas what I'm doing wrong?
And this is the error:
Received an error from the server
An error occured
An error occurred when trying to create a controller of type 'EntityController'. Make sure that the controller has a parameterless public constructor.
Exception Details
System.InvalidOperationException: An error occurred when trying to create a controller of type 'EntityController'. Make sure that the controller has a parameterless public constructor.
Stacktrace
at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType)
at System.Web.Http.Controllers.HttpControllerDescriptor.CreateController(HttpRequestMessage request)
at System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__15.MoveNext()
Inner Exception
System.InvalidOperationException: Unable to resolve type: Umb.Test.Core.Composers.ContentSearchExtender, service name:
at LightInject.ServiceContainer.CreateDelegate(Type serviceType, String serviceName, Boolean throwError) in C:\projects\lightinject\src\LightInject\LightInject.cs:line 4748
at LightInject.ServiceContainer.CreateDefaultDelegate(Type serviceType, Boolean throwError) in C:\projects\lightinject\src\LightInject\LightInject.cs:line 4705
at LightInject.ServiceContainer.GetInstance(Type serviceType) in C:\projects\lightinject\src\LightInject\LightInject.cs:line 3437
at Umbraco.Core.Composing.LightInject.LightInjectContainer.GetInstance(Type type) in D:\a\1\s\src\Umbraco.Core\Composing\LightInject\LightInjectContainer.cs:line 111
at Umbraco.Core.Composing.CollectionBuilderBase`3.CreateItem(IFactory factory, Type itemType) in D:\a\1\s\src\Umbraco.Core\Composing\CollectionBuilderBase.cs:line 111
at Umbraco.Core.Composing.CollectionBuilderBase`3.<>c__DisplayClass10_0.<CreateItems>b__0(Type x) in D:\a\1\s\src\Umbraco.Core\Composing\CollectionBuilderBase.cs:line 103
at System.Linq.Enumerable.WhereSelectArrayIterator`2.MoveNext()
at System.Linq.Buffer`1..ctor(IEnumerable`1 source)
at System.Linq.Enumerable.ToArray[TSource](IEnumerable`1 source)
at Umbraco.Core.Composing.CollectionBuilderBase`3.CreateItems(IFactory factory) in D:\a\1\s\src\Umbraco.Core\Composing\CollectionBuilderBase.cs:line 102
at Umbraco.Core.Composing.CollectionBuilderBase`3.CreateCollection(IFactory factory) in D:\a\1\s\src\Umbraco.Core\Composing\CollectionBuilderBase.cs:line 120
at Umbraco.Core.Composing.LightInject.LightInjectContainer.<>c__DisplayClass20_0`1.<Register>b__0(IServiceFactory f) in D:\a\1\s\src\Umbraco.Core\Composing\LightInject\LightInjectContainer.cs:line 172
at DynamicMethod(Object[] )
at LightInject.ServiceContainer.<>c__DisplayClass150_0.<WrapAsFuncDelegate>b__0() in C:\projects\lightinject\src\LightInject\LightInject.cs:line 3798
at LightInject.PerRequestLifeTime.GetInstance(Func`1 createInstance, Scope scope) in C:\projects\lightinject\src\LightInject\LightInject.cs:line 6207
at DynamicMethod(Object[] )
at LightInject.ServiceContainer.<>c__DisplayClass150_0.<WrapAsFuncDelegate>b__0() in C:\projects\lightinject\src\LightInject\LightInject.cs:line 3798
at LightInject.PerRequestLifeTime.GetInstance(Func`1 createInstance, Scope scope) in C:\projects\lightinject\src\LightInject\LightInject.cs:line 6207
at DynamicMethod(Object[] )
at LightInject.ServiceContainer.TryGetInstance(Type serviceType) in C:\projects\lightinject\src\LightInject\LightInject.cs:line 3498
at LightInject.WebApi.LightInjectWebApiDependencyScope.GetService(Type serviceType) in C:\projects\lightinject-webapi\build\tmp\Net46\Binary\LightInject.WebApi\LightInject.WebApi.cs:line 187
at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.GetInstanceOrActivator(HttpRequestMessage request, Type controllerType, Func`1& activator)
at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType)
Inner Exception
System.InvalidOperationException: Unresolved dependency [Target Type: Umb.Test.Core.Composers.ContentSearchExtender], [Parameter: tagSearcher(Umb.Test.Core.Shared.TagSearcher)], [Requested dependency: ServiceType:Umb.Test.Core.Shared.TagSearcher, ServiceName:]
at LightInject.ServiceContainer.GetEmitMethodForDependency(Dependency dependency) in C:\projects\lightinject\src\LightInject\LightInject.cs:line 4207
at LightInject.ServiceContainer.EmitConstructorDependency(IEmitter emitter, Dependency dependency) in C:\projects\lightinject\src\LightInject\LightInject.cs:line 4154
at LightInject.ServiceContainer.EmitConstructorDependencies(ConstructionInfo constructionInfo, IEmitter emitter, Action`1 decoratorTargetEmitter) in C:\projects\lightinject\src\LightInject\LightInject.cs:line 4120
at LightInject.ServiceContainer.EmitNewInstanceUsingImplementingType(IEmitter emitter, ConstructionInfo constructionInfo, Action`1 decoratorTargetEmitMethod) in C:\projects\lightinject\src\LightInject\LightInject.cs:line 4080
at LightInject.ServiceContainer.EmitNewInstance(ServiceRegistration serviceRegistration, IEmitter emitter) in C:\projects\lightinject\src\LightInject\LightInject.cs:line 4034
at LightInject.ServiceContainer.EmitNewInstanceWithDecorators(ServiceRegistration serviceRegistration, IEmitter emitter) in C:\projects\lightinject\src\LightInject\LightInject.cs:line 3929
at LightInject.ServiceContainer.<>c__DisplayClass197_0.<ResolveEmitMethod>b__2(IEmitter ms) in C:\projects\lightinject\src\LightInject\LightInject.cs:line 4649
at LightInject.ServiceContainer.CreateDynamicMethodDelegate(Action`1 serviceEmitter) in C:\projects\lightinject\src\LightInject\LightInject.cs:line 3776
at LightInject.ServiceContainer.CreateInstanceDelegateIndex(Action`1 emitMethod) in C:\projects\lightinject\src\LightInject\LightInject.cs:line 4693
at LightInject.ServiceContainer.<>c__DisplayClass198_0.<EmitLifetime>b__2(ServiceRegistration _) in C:\projects\lightinject\src\LightInject\LightInject.cs:line 4664
at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory)
at LightInject.ServiceContainer.EmitLifetime(ServiceRegistration serviceRegistration, Action`1 emitMethod, IEmitter emitter) in C:\projects\lightinject\src\LightInject\LightInject.cs:line 4664
at LightInject.ServiceContainer.<>c__DisplayClass197_0.<ResolveEmitMethod>b__1(IEmitter methodSkeleton) in C:\projects\lightinject\src\LightInject\LightInject.cs:line 4649
at LightInject.ServiceContainer.<>c__DisplayClass153_0.<CreateEmitMethodWrapper>b__0(IEmitter ms) in C:\projects\lightinject\src\LightInject\LightInject.cs:line 3856
at LightInject.ServiceContainer.CreateDynamicMethodDelegate(Action`1 serviceEmitter) in C:\projects\lightinject\src\LightInject\LightInject.cs:line 3776
at LightInject.ServiceContainer.CreateDelegate(Type serviceType, String serviceName, Boolean throwError) in C:\projects\lightinject\src\LightInject\LightInject.cs:line 4743
the ISearchableTree interface only works with actual trees.
So your class can't only implement the interface. It's more an addition to backend trees. So you have to inherit from TreeController to make it an actual tree.
Then I might be going about the problem all wrong. I am not trying to make a new tree happen.
I'm trying to expand the search in the existing content tree and media section, so that if I search for "butterfly" every piece of content, and media tagged with butterfly shows up as a result.
Thing is.. It's working. But only with one of the searcher enabled at the time. It's only when I compose in both of them I get errors.
Do I need to go about this differently?
Here is a picture of it "working" but only for content and not media, since I have commented out the composing part of MediaSearchExtender
Interesting that it works without being an actual tree.
In the StackTrace of the error it says System.InvalidOperationException: Unresolved dependency [Target Type: Umb.Test.Core.Composers.ContentSearchExtender], [Parameter: tagSearcher(Umb.Test.Core.Shared.TagSearcher)], [Requested dependency: ServiceType:Umb.Test.Core.Shared.TagSearcher, ServiceName:].
So it could be that the registration for the TagSearcher is not correct when you are using both trees.
I'm not sure if the RegisterFor stuff is working as expected in that scenario.
See here for an explanation on how it should be used. That would at least be my current guess.
My try would be to register the TagSearch as a singleton once. Maybe that helps.
Can't get two ISearchableTree implementations to work at the same time
I'm toying around in Umbraco Backoffice with making the search function return extra results, dependent on tags put on documents or media.
They both work, separatly, but if I compose in both of them, everything breaks. Doesn't matter which one. I am probably missing something very simple.
I have made two ISearchableTree implementations looking like this:
For content search and For media search.
This is my "TagSearcher" by the way
As said, when only one (lets say I comment out the compose part in the AddMediaSearchExtender) is enabled, they perform as expected. If both are enabled, I get this error:
Any ideas what I'm doing wrong?
And this is the error:
Hi Kaspar,
the ISearchableTree interface only works with actual trees. So your class can't only implement the interface. It's more an addition to backend trees. So you have to inherit from TreeController to make it an actual tree.
See here: https://our.umbraco.com/Documentation/Extending/Section-Trees/trees
That's what the error states something about controller and parameterless constructor.
Hope that helps :)
Then I might be going about the problem all wrong. I am not trying to make a new tree happen.
I'm trying to expand the search in the existing content tree and media section, so that if I search for "butterfly" every piece of content, and media tagged with butterfly shows up as a result.
Thing is.. It's working. But only with one of the searcher enabled at the time. It's only when I compose in both of them I get errors.
Do I need to go about this differently?
Here is a picture of it "working" but only for content and not media, since I have commented out the composing part of MediaSearchExtender
Interesting that it works without being an actual tree.
In the StackTrace of the error it says
System.InvalidOperationException: Unresolved dependency [Target Type: Umb.Test.Core.Composers.ContentSearchExtender], [Parameter: tagSearcher(Umb.Test.Core.Shared.TagSearcher)], [Requested dependency: ServiceType:Umb.Test.Core.Shared.TagSearcher, ServiceName:]
.So it could be that the registration for the TagSearcher is not correct when you are using both trees.
I'm not sure if the RegisterFor stuff is working as expected in that scenario. See here for an explanation on how it should be used. That would at least be my current guess.
My try would be to register the TagSearch as a singleton once. Maybe that helps.
Thanks, that did the trick. Removing the RegisterFor on my second composition made the solution click.
Just wanted to ping and say: Cool idea! Got inspirerad to start toying around :)
is working on a reply...