Monday, October 21, 2019

Glass Mapper Upgrade V5

What is needed

Since the release of Glass Mapper 5.0.2, Glass Mapper announced that it will no longer support older versions for errors. Check out here So starting from Sitecore 9, you should upgrade Glass Mapper versions.

How

ISitecoreContext is removed, we have 3 different ones now:
  • IMvcContext
  • IRequestContext
  • IWebFormsContext
Now we have to register all of these services with Sitecore container:
 public class GlassMapperConfigurator : IServicesConfigurator
    {
        public void Configure(IServiceCollection serviceCollection)
        {
            serviceCollection.AddScoped<ISitecoreService>(sp => new SitecoreService(Sitecore.Context.Database));
            serviceCollection.AddScoped<IMvcContext>(sp => new MvcContext(sp.GetService<ISitecoreService>()));
            serviceCollection.AddScoped<IRequestContext>(sp => new RequestContext(sp.GetService<ISitecoreService>()));
            serviceCollection.AddScoped<IGlassHtml>(sp => new GlassHtml(sp.GetService<ISitecoreService>()));
        }
    }

Then, patch this configurator using the following:
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
  <sitecore>
    <services>
      <configurator type="Foundation.Glass.GlassMapperConfigurator, Foundation.Glass" />
    </services>
  </sitecore>
</configuration>

If you are using Helix(and you should), you can create a foundation project for Glass, add nuget package for your version Glass.Mapper.Sc.{sitecoreVersion} and add service injections there:

public class GlassFactory : IGlassFactory
{
   public ISitecoreService GetSitecoreService() => Sitecore.DependencyInjection.ServiceLocator.ServiceProvider.GetService<ISitecoreService>();
   public IRequestContext GetRequestContext() => Sitecore.DependencyInjection.ServiceLocator.ServiceProvider.GetService<IRequestContext>();
   public IMvcContext GetMvcContext() => Sitecore.DependencyInjection.ServiceLocator.ServiceProvider.GetService<IMvcContext>();
}

We inject Glass services using Sitecore service locator.

In order to use these services in another project(Feature, Foundation etc), you have to first add a reference to your Glass Project. Then, add a nuget package for Glass.Mapper.Sc.{sitecoreVersion}.Mvc and Glass.Mapper.Sc.{sitecoreVersion}.Core. You can use WebForms too, if you want to map items from there.

Then, we can use this factory to get services we want. For instance, if you want to map Item to your class model:

var sitecoreContext = glassFactory.GetSitecoreService();
var mappedItem = sitecoreContext.GetItem<ClassModel>(Item);

If you want to use glass mapper in Controller, inheriting from GlassController is removed. We are using MvcContext instead, ie. getting DataSource item:

var mappedItem = glassFactory.GetMvcContext().GetDataSourceItem<DatasourceClassModel>();

This is the simplest solution, if you want to use Glass mapper in different projects and you have many. 

Friday, May 10, 2019

Sitecore Rule Based Configuration

Sitecore Role Configuration

Starting from Sitecore 9, you can use Rule Based Configuration to choose which configuration should be applied for each Sitecore instance. Sitecore already has 2 predefined rules, Role and Search, but we will also use a custom one.
You can find the documentation here: Rule-based configuration

What is needed

We had 3 server roles (Standalone, Content Delivery, Content Management) for our instances. The instances are configured according to its roles and that was causing too many config files. 

What is achieved

  • Made configuration settings dependent on a rule
  • Easy to manipulate, assign

How

If you hadn't already separate your AppSettings, you can start by doing that. Then you should simply add a reference to your AppSettings on web.config. 

<appSettings configSource="App_Config\AppSettings.config" />

On your AppSettings.config file, you can define your rules.

But also, you can separate each environment and define these environment specific settings there. You should add a reference to these files and name them same as your referenced file at top of your main AppSettings.config:

<appSettings file="EnvironmentAppSettings.config">

You can add the following to EnvironmentAppSettings.config for your local environment for rule configuration: 

<add key="role:define" value="Standalone" />
<add key="env:define" value="Local"/>

EnvironmentAppSettings should include what you need at this point, for instance Acceptence Content Delivery server can have the following: 

<appSettings>
<add key="role:define" value="ContentDelivery"/>
<add key="env:define" value="Acceptance"/>
</appSettings>

To start using these rules, whether they are custom or not, in your configuration, you should also register them at top. For example, following adds the custom "env" rule:

<configuration xmlns:env="http://www.sitecore.net/xmlconfig/env">

Then you can use them in each setting:

<sc.variable name="dataFolder" env:require="Acceptence" value="\Data" />

You can customize rule values according to your needs. If you need a setting to work on your both Acceptence and Production environments: 

env:require="Acceptence or Production"

or you want it to work on only Content Delivery server: 

env:require="Acceptence or Production" role:require="ContentDelivery"

or you want it not to work on one environment: 

env:require="!Local"