This blog post gives you early information on Release 4.3 of Glass.Mapper.Sc! Check out the new features and let us know what you think.

Pipeline Changes

In this release we have changed how pipelines are handled by Glass.Mapper. We are no longer using the Sitecore style pipelines where each task in the pipeline is automatically called after the previous task unless an abort has been called.

Instead we are moving to the Middleware pipeline style used by the new ASP.NET Core MVC where a task explicitly calls the next task in the pipeline or decides to do something else. We have made this change for several reasons:

  • It provides you with much more control about how the pipeline executes. You can easily decided to branch the pipeline and do something completely different.
  • Simplifies logic that is dependant on tasks that follow. For example in the original pipeline style we needed two tasks for caching. The first task would check the cache and the second task would add an object to the cache. This can now be combined into one single cache task making the logic much simpler.
  • Ability to handle exceptions in the pipeline. If a tasks after your task throws an exception then your task can now handle it.
  • Allows more advanced features to be developed. For example the cachable lazy load disabler discussed later.

So what has changed?

Firstly the following interfaces have been replaced with abstract classes:

  • IObjectSavingTask to AbstractObjectSavingTask
  • IObjectConstructionTask to AbstractObjectConstructionTask
  • IDataMapperResolverTask to AbstractDataMapperResolverTask
  • IConfigurationResolverTask to AbstractConfigurationResolverTask

All pipeline tasks now inherit from the AbstractPipelineTask which contains two important methods:

  • Execute - Called by the framework to perform an action in the pipeline.
  • Next - Use to call the next task in the pipeline.

Normally you can just override the Execute method and when you are ready to call the next task in the pipeline you simple call base.Execute, for example:

public class MyTask : AbstractObjectConstructionTask{
              public override void Execute(ObjectConstructionArgs args)
               { 
                //do some work
                base.Execute(args);
                }
}

Any tasks that you have already created pre version 4.3 will need to be updated to work with this approach. For more information on how a Middleware pipeline works please read Microsoft information:

https://docs.microsoft.com/en-us/aspnet/core/fundamentals/middleware

Cachable Changes

One of the many great features of Glass.Mapper is the ability to cache your models and then reuse them almost anywhere in your solution. However this came with one restriction, you need to turn off lazy loading for any properties that referenced other Sitecore items. This was to ensure that all data was loaded in the same context as the originally requested model. A model would look like this:

public class MyModel {
   [SitecoreParent(IsLazy=false)]
   public virtual MyParent Parent { get; set; }
        
   [SitecoreChildren(IsLazy=false)]
   public virtual MyChild Children {get; set; }
}

This solution had several problems:

  • Remembering to add IsLazy = false to the correct properties.
  • The class isn’t reusable in scenarios where Lazy Loading should be enabled.
  • Linked classes, e.g. MyParent and MyChild in the example, may contain further properties where lazy loading needs to be disabled.
  • To easy to make a mistake.

In this release we have introduced the DisableLazyLoading class. If your model has been marked as Cachable then we will automatically disable lazy loading while the model is constructed which includes all models generated via property references. Therefore if your mark a model as cachable you no longer need to set the IsLazy = false flag. We have also added a depth check mechanism that attempts to detect if a cached model contains a loop. This is achieved by counting the depth of the models created, for example the requested model is at depth 1, a model mapped to a property of this model is depth 2, a model mapped to that model is depth 3 and so on. The depth check allows a maximum depth of 8 before throwing an exception.

If you wish to disable these new features you can use the following code:

            var factory =
                dependencyResolver.ObjectConstructionFactory as AbstractConfigFactory<AbstractObjectConstructiontask>;
            factory.Remove<ModelDepthCheck>();
            config.EnableLazyLoadingForCachableModels = true;

This feature can be controlled by the config setting EnableLazyLoadingForCachableModels which is set to true by default.

Diagnostic Changes

We have update the diagnostic information we supply so that it gives more information. Once diagnostics have been enabled you will be able to monitor the following object creation information:

  • Proxy Models Created
  • Total Models Mapped - not all models are mapped because of lazy loading but proxy maybe generated.
  • Total Models Requested
  • Cached models returned
  • Concrete models created - e.g. models that didn’t require a proxy object to be created (interfaces and lazy loading).

GetModelFromView

We have been working on some improvements to the GetModelFromView processor after a report of a performance problem by Alex (Issue 253). From out testing it seems that the first load of any CSHTML files would take a long time. This was caused by the compiling of the CSHTML file using the BuildManager.GetCompiledType method. Added to this we were also compiling Sitecore SPEAK views.

To solve this we have made to changes, firstly any request for a CSHTML file when the site is Shell will be ignored (we assume it is a SPEAK view). Secondly we have extracted how we find the target type. By default Glass will now use a Regex resolver which is significantly quicker. Since this has been abstracted you can now swap this for alternative implementations if you need something more specific and we have created a resolver that works with Compile Razor views which we will blog soon!

If you find issues with the Regex View Resolve causes issue with your solution you can configure Glass to use the original version with this code:

        GetModelFromView.ViewTypeResolver = new ChainedViewTypeResolver(
                new IViewTypeResolver[] {
                    new RegexViewTypeResolver(),
                    new BuildManagerViewTypeResolver()
                   });

This code can be added to the PostLoad event of the GlassMapperScCustom class.

Unit Tests

We have spent a lot of time getting unit tests running on the build server and we have now successfully got the majority of them running. Unit tests on the build server are run against Sitecore versions 8.0, 8.1 and 8.2 with a total of 2200+ tests run per build!

We have also fully embraced Sitecore FakeDB making it much easier for contributors to test their changes.

comments powered by Disqus