无法解析“ Jabberwocky.Core.Caching.ICacheProvider”类型的服务

时间:2019-01-24 17:20:38

标签: c# .net dependency-injection sitecore

我正在从Sitecore 8.2升级到9.1。加载仪表板时出现以下错误:

Server Error in '/' Application.
Unable to resolve service for type 'Jabberwocky.Core.Caching.ICacheProvider' while attempting to activate 'CCO.Foundation.SitecoreExtensions.Pipelines.GetXmlBasedLayoutDefinition.InsertCascadedRenderings'.
Description: An unhandled exception occurred. 

Exception Details: System.InvalidOperationException: Unable to resolve service for type 'Jabberwocky.Core.Caching.ICacheProvider' while attempting to activate 'CCO.Foundation.SitecoreExtensions.Pipelines.GetXmlBasedLayoutDefinition.InsertCascadedRenderings'.

Source Error: 

An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.

Stack Trace: 


[InvalidOperationException: Unable to resolve service for type 'Jabberwocky.Core.Caching.ICacheProvider' while attempting to activate 'CCO.Foundation.SitecoreExtensions.Pipelines.GetXmlBasedLayoutDefinition.InsertCascadedRenderings'.]
   Microsoft.Extensions.DependencyInjection.ConstructorMatcher.CreateInstance(IServiceProvider provider) +405
   Sitecore.Configuration.DefaultFactory.CreateFromServiceProvider(XmlNode configNode, Boolean assert) +481

[ConfigurationException: Could not create object from service provider . Config XML: <processor type="CCO.Foundation.SitecoreExtensions.Pipelines.GetXmlBasedLayoutDefinition.InsertCascadedRenderings, CCO.Foundation.SitecoreExtensions" resolve="true" patch:source="CCO.Foundation.SitecoreExtensions.config" xmlns:patch="http://www.sitecore.net/xmlconfig/" />]
   Sitecore.Configuration.DefaultFactory.CreateFromServiceProvider(XmlNode configNode, Boolean assert) +641
   Sitecore.Configuration.DefaultFactory.CreateObject(XmlNode configNode, String[] parameters, Boolean assert, IFactoryHelper helper) +138
   Sitecore.Configuration.DefaultFactory.CreateObject(XmlNode configNode, Boolean assert) +68
   Sitecore.Pipelines.CorePipelineFactory.GetObjectFromType(XmlNode processorNode) +91
   Sitecore.Pipelines.CorePipelineFactory.GetProcessorObject(XmlNode processorNode) +145
   Sitecore.Pipelines.CoreProcessor.GetMethod(Object[] parameters) +136
   Sitecore.Pipelines.CorePipeline.Run(PipelineArgs args) +470
   Sitecore.Pipelines.DefaultCorePipelineManager.Run(String pipelineName, PipelineArgs args, String pipelineDomain, Boolean failIfNotExists) +236
   Sitecore.Pipelines.DefaultCorePipelineManager.Run(String pipelineName, PipelineArgs args, String pipelineDomain) +22
   Sitecore.Mvc.Pipelines.PipelineService.RunPipeline(String pipelineName, TArgs args) +195
   Sitecore.Mvc.Pipelines.PipelineService.RunPipeline(String pipelineName, TArgs args, Func`2 resultGetter) +161
   Sitecore.Mvc.Pipelines.Response.BuildPageDefinition.ProcessXmlBasedLayoutDefinition.AddRenderings(PageDefinition pageDefinition, BuildPageDefinitionArgs args) +265
   (Object , Object ) +14
   Sitecore.Pipelines.CorePipeline.Run(PipelineArgs args) +484
   Sitecore.Pipelines.DefaultCorePipelineManager.Run(String pipelineName, PipelineArgs args, String pipelineDomain, Boolean failIfNotExists) +236
   Sitecore.Pipelines.DefaultCorePipelineManager.Run(String pipelineName, PipelineArgs args, String pipelineDomain) +22
   Sitecore.Mvc.Pipelines.PipelineService.RunPipeline(String pipelineName, TArgs args) +195
   Sitecore.Mvc.Pipelines.PipelineService.RunPipeline(String pipelineName, TArgs args, Func`2 resultGetter) +161
   Sitecore.Mvc.Presentation.PageContext.GetPageDefinition() +297
   Sitecore.Mvc.Presentation.PageContext.get_PageDefinition() +31
   Sitecore.Mvc.Presentation.PageContext.GetPageView() +126
   Sitecore.Mvc.Presentation.PageContext.get_PageView() +31
   Sitecore.Mvc.Controllers.SitecoreController.GetDefaultAction() +26
   lambda_method(Closure , ControllerBase , Object[] ) +90
   System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters) +35
   System.Web.Mvc.Async.<>c.<BeginInvokeSynchronousActionMethod>b__9_0(IAsyncResult asyncResult, ActionInvocation innerInvokeState) +39
   System.Web.Mvc.Async.WrappedAsyncResult`2.CallEndDelegate(IAsyncResult asyncResult) +70
   System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethod(IAsyncResult asyncResult) +42
   System.Web.Mvc.Async.AsyncInvocationWithFilters.<InvokeActionMethodFilterAsynchronouslyRecursive>b__11_0() +72
   System.Web.Mvc.Async.<>c__DisplayClass11_1.<InvokeActionMethodFilterAsynchronouslyRecursive>b__2() +387
   System.Web.Mvc.Async.<>c__DisplayClass11_1.<InvokeActionMethodFilterAsynchronouslyRecursive>b__2() +387
   System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethodWithFilters(IAsyncResult asyncResult) +42
   System.Web.Mvc.Async.<>c__DisplayClass3_6.<BeginInvokeAction>b__3() +50
   System.Web.Mvc.Async.<>c__DisplayClass3_1.<BeginInvokeAction>b__5(IAsyncResult asyncResult) +39

Startup.cs:

using CCO.Foundation.SitecoreExtensions.Pipelines.GetXmlBasedLayoutDefinition;
using Microsoft.Extensions.DependencyInjection;
using Jabberwocky.Core.Caching;

namespace CCO.Foundation.SitecoreExtensions.App_Start
{
    public class Startup
    {
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddSingleton(typeof(ICacheProvider), typeof(InsertCascadedRenderings));
        }
    }
}

被调用的类使用Jabberwocky ICacheProvider接口:

using System;
using Jabberwocky.Core.Caching;
using Jabberwocky.DependencyInjection.Autowire.Attributes;

namespace CCO.Foundation.SitecoreExtensions.Pipelines.GetXmlBasedLayoutDefinition
{
    using System.Collections.Generic;
    using System.Linq;
    using System.Xml.Linq;
    using Sitecore;
    using Sitecore.Data.Fields;
    using Sitecore.Data.Items;
    using Sitecore.Diagnostics;
    using Sitecore.Layouts;
    using Sitecore.Mvc.Devices;
    using Sitecore.Mvc.Pipelines.Response.GetXmlBasedLayoutDefinition;
    using PageContext = Sitecore.Mvc.Presentation.PageContext;
    using Extensions;
    using Sitecore.Data;

    [AutowireService]
    public class InsertCascadedRenderings : GetXmlBasedLayoutDefinitionProcessor
    {
        private readonly ICacheProvider _cacheProvider;

        public InsertCascadedRenderings(ICacheProvider cacheProvider)
        {
            _cacheProvider = cacheProvider;
        }

        public override void Process(GetXmlBasedLayoutDefinitionArgs args)
        {
            if (args?.Result == null) return;

            Item item = PageContext.Current.Item;
            Device device = PageContext.Current.Device;

            if (item?.Parent == null || device == null) return;

            if (Context.PageMode.IsNormal)
            {
                args.Result = _cacheProvider.GetFromCache($"CascadedRenderings:{item.ID}:{device.Id}",
                    () => MergeWithCascadedRenderings(args.Result, item, device));
            }
            else
            {
                args.Result = MergeWithCascadedRenderings(args.Result, item, device);
            }

            Log.Debug($"The result of merge is:\n{args.Result}");
        }

        protected virtual XElement MergeWithCascadedRenderings(XElement self, Item currentItem, Device device)
        {
            Assert.ArgumentNotNull(self, "self");
            Assert.ArgumentNotNull(currentItem, "currentItem");
            Assert.ArgumentNotNull(device, "device");
            LayoutDefinition selfParsed = LayoutDefinition.Parse(self.ToString());

            string deviceId = $"{{{device.Id.ToString().ToUpper()}}}";

            DeviceDefinition selfDevice = selfParsed.GetDevice(deviceId);

            var renderings = new List<RenderingDefinition>();
            var pageRenderings = Enumerable.Empty<RenderingDefinition>();
            Field layoutField = currentItem.Fields[FieldIDs.FinalLayoutField];

            LayoutDefinition pageParsed = LayoutDefinition.Parse(LayoutField.GetFieldValue(layoutField));

            DeviceDefinition pageDevice = pageParsed.GetDevice(deviceId);

            if (pageDevice.Renderings != null)
            {
                pageRenderings = pageDevice.Renderings.Cast<RenderingDefinition>();
            }
            //start cascaded renderings from item parent and iterate up to home item
            foreach (var ancestor in currentItem.Axes.GetAncestors().Reverse())
            {
                if(ancestor.Visualization.Layout == null)continue;

                renderings.AddRange(GetItemRenderingDefinitions(ancestor, deviceId, pageRenderings));
            }
            //iterate through all renderings set to cascade

            foreach (var rendering in renderings.Distinct(new RenderingDefinitionEqualityComparer()))
            {
                if (rendering == null)
                {
                    continue;
                }
                //verify that each rendering only cascades once
                if (!selfDevice.Renderings.Cast<RenderingDefinition>()
                    .Any(x => x.ItemID == rendering.ItemID
                            && StringUtil.ExtractParameter("Cascade", x.Parameters ?? "") == "1"))
                {

                    // we're inserting first due to page banners and heros that can be cascaded.
                    // these will (should?) always be the first components in body content
                    selfDevice.AddRendering(rendering);
                }
            }

            return XDocument.Parse(selfParsed.ToXml()).Root;
        }
        /// <summary>
        /// Get cascaded renderings defined on item
        /// </summary>
        /// <param name="item"></param>
        /// <param name="deviceId"></param>
        /// <returns></returns>
        protected virtual IEnumerable<RenderingDefinition> GetItemRenderingDefinitions(Item item, string deviceId, IEnumerable<RenderingDefinition> pageRenderings)
        {
            Assert.ArgumentNotNull(item, "item");
            Field layoutField = item.Fields[FieldIDs.FinalLayoutField];

            LayoutDefinition parentParsed = LayoutDefinition.Parse(LayoutField.GetFieldValue(layoutField));

            DeviceDefinition parentDevice = parentParsed.GetDevice(deviceId);

            if (parentDevice.Renderings == null) return Enumerable.Empty<RenderingDefinition>(); // empty layout

            var allRenderings = parentDevice.Renderings.Cast<RenderingDefinition>();
            var cascadedRenderings = allRenderings.Where(r => StringUtil.ExtractParameter("Cascade", r.Parameters ?? string.Empty) == "1");

            var allAddedRenderings = new List<RenderingDefinition>();
            foreach (var rendering in cascadedRenderings)
            {
                rendering.Parameters = $"{rendering.Parameters}&Editable=0";


                // all containers use dynamic placholders.
                if (rendering.IsInDynamicPlaceholder())
                {
                    var parentId = rendering.GetIdFromDynamicPlaceholder();
                    var parentRendering = allRenderings.FirstOrDefault(r => r.UniqueId == new ID(parentId).ToString());
                    var parentPageRendering = pageRenderings.FirstOrDefault(r => r.ItemID == parentRendering.ItemID);
                    if (parentPageRendering != null)
                    {
                        rendering.Placeholder = rendering.Placeholder.Replace(parentId, new Guid(parentPageRendering.UniqueId).ToString());
                    }
                    else
                    {
                        allAddedRenderings.Add(parentRendering);
                    }
                }

                allAddedRenderings.Add(rendering);
            }

            return allAddedRenderings;
        }
    }

    public class RenderingDefinitionEqualityComparer : IEqualityComparer<RenderingDefinition>
    {
        public bool Equals(RenderingDefinition x, RenderingDefinition y)
        {
            return x?.ItemID == y?.ItemID;
        }

        public int GetHashCode(RenderingDefinition obj)
        {
            return obj?.ItemID?.GetHashCode() ?? 0;
        }
    }
}

我已经研究了好几天,尝试了所有发现的建议,但仍然无法解决此错误。我对使用DI很陌生。

谢谢。

0 个答案:

没有答案