Implementing Dependency Injection With Sitecore

While we have excellent blog by Kam as well as official Sitecore documentation is available for setting up DI with Sitecore, This blog is intend to provide step by step guide for beginners to understand & implement DI with Sitecore.

I’ve used Sitecore 9 for this, but it should work with Sitecore 8.2 as well (this is when Sitecore included built-in DI).

What is Dependency Injection?

Dependency Injection is a process of supplying the required resources (dependencies) to the code which requires these resources.
DI allow developers to build loosely coupled components as we make our components depended upon the Interfaces rather than depending on the actual implementation.

See this Stackoverflow link for more information.

With Dependency Injection, instead of using direct & hard-coded instances we inject dependencies (how? we will see that later) to the components & make them aware that they will need injected dependency to serve the purpose.

Let’s try to understand DI with a simple example:

Below we have a class (or Component) Consumer, which depend on another classes called ServiceA & ServiceB.


public class Consumer
{
    // Other properties of Consumer class
    string Name;
    ...
    ...
    // Service class dependencies
    ServiceA _serviceA
    ServiceB _serviceB;;

    // Public constructor
    public Consumer()
    {
        Name="Some Name";
        // Initiating service objects
        _serviceA= new ServiceA();
        _serviceB= new ServiceB();
    }
    
    public void ConsumeService() {
        _serviceA.ExecuteService();
        _serviceB.ExecuteService();
    }
}

Both these service classes has ExecuteService method to perform some logic:

public class ServiceA
{
    public void ExecuteService()
    {
        // Some code logic for ServiceA
    }
}

public class ServiceB
{
    public void ExecuteService()
    {
        // Some code logic for ServiceB
    }
}

Here Consumer & Service classes are tightly coupled.
To abstract the above code, let’s introduce an interface, IService:


public interface IService
{
    public void ExecuteService();
}

And service classes will implement this interface:

public class ServiceA : IService
{
    public void ExecuteService() 
    {
        // Some code logic for ServiceA

    }
}

public class ServiceB : IService
{
    public void ExecuteService()
    {
        // Some code logic for ServiceB
    }
}

We will now use the IService interface in Consumer class:

public class Consumer
{
    // Other properties of Consumer class
    string Name;
    ...
    ...
    // Service class dependency using interface
    IService _service;

    // Public constructor
    public Consumer()
    {
        // Initiating other properties
        Name="Some Name";
        // Initiating service interface dependency by ServiceA
        _service= new ServiceA();
        // or if we need to initiate by ServiceB 
        // _service= new ServiceB();
    }
    
    // Method to call ExecuteService of IService interface
    public void ConsumeService()
    {
       _service.ExecuteService();
    }
}

Still Consumer class need to use either ServiceA or ServiceB to initiate the IService object, so we still have dependency on ServiceA & ServiceB.

What if we can modify our code as below:


public class Consumer
{
    // Other properties of Consumer class
    string Name;
    // No Service class dependency, instead it will depend on the interface
    IService _service;

    // Public constructor
    public Consumer(IService service)
    {
        Name="Some Name";
        // Initiating using constructor parameter
       _service= service;
    }
    // Method to call ExecuteService of IService interface
    public void ConsumeService()
    {
        _service.ExecuteService();
    }
}

We have removed the dependencies of ServiceA & ServiceB from Consumer class & now it depends on the interface IService instead of the implementation.

How we did that?

We are passing the object of IService in the constructor to initiate the IService object _service, in other words we are injecting the dependency.
Injecting dependencies can be done via different techniques such as :
Construction Injection (as we just did),
Property Injection &
Method Injection

Still, which class will initiate the IService object & which ExecuteService method will be called?

IService interface have multiple implementations & based on the our requirement (ServiceA or ServiceB), we can choose which one we want to use.

This choosing part is known as Service Registration & often done using a IoC Container such as Autofac/Castle Windsor/Unity/Simple Injector and many more OR you can use the default one).
With Service Registration, we declare how dependencies should be resolved & it is done in a separate class which will be called when the application starts.

For example, to resolve the IService dependency with ServiceA, we may register as below (done using built-in DI supported by Sitecore):


public class RegisterDependencies : IServicesConfigurator
{
    public void Configure(IServiceCollection serviceCollection)
    {
        // This is the line to register the dependency
        serviceCollection.AddTransient(typeof(IService), typeof(ServiceA));
    }
}

This code could vary as per the IoC container we choose (don’t worry about this).
With the example code above, when our application starts, it will know that IService objects needs to be initiated by ServiceA.

Consumer class now only depends on interface IService & in case we now want to resolve dependency by ServiceB, we can update the service registration as below:


public class RegisterDependencies : IServicesConfigurator
{
    public void Configure(IServiceCollection serviceCollection)
    {
        serviceCollection.AddTransient(typeof(IService), typeof(ServiceB));
    }
}

How this is loosely coupled?

In case we want to delete ServiceA or ServiceB OR if we want to introduce a new class ServiceC, we don’t need to change anything in the Consumer class & it doesn’t need to know what’s going in the background.

Consumer class is a high-level component, which is loosely coupled with low level components (ServiceA or ServiceB) through the interface IService.
This is Inversion Of Control (IoC) principal.
DI follows IoC principal & often these terms are used interchangeably.

As I mentioned before, with Sitecore 8.2 onward, we can use the built-in DI to register our dependencies.

In the example above it would seem like that we are adding the complexity just for a small piece of code but in real case, you will have tonnes of components to deal with and DI will help to make the application decoupled & flexible.

I hope I was able to give you some basic information about the Dependency Injection, in case you want to read more follow this link.

In terms of setting up DI with Sitecore, we mainly do three things:

First thing – Use interfaces & implement them.
Secondly- Register dependencies &
Lastly – Injecting dependencies.

We will now perform these 3 steps & see things happening.

In our example we will show the list of employees from Sitecore.

I created a Controller “EmployeeListingController“, added an Controller Action “GetAllEmployees” and lastly created associated Controller rendering.

Now we will perform our first step of DI – use interface & implement it.
I’m going to create the Repository folder in the project & define an interface called IEmployeeListing.

This is what interface has:


public interface IEmployeeListing
{

    List<Item> GetEmployees();
}

We will implement this interface using EmployeeListing class & here is how it looks:


public class EmployeeListing : IEmployeeListing
{

    public List<Item> GetEmployees()
    {
        List<Item> employees = new List<Item>();

        var home = Sitecore.Context.Database.GetRootItem();

        foreach (Item employeeItem in home.Children)
        {
             employees.Add(employeeItem);
        }

        return employees;

    }
}

Now we will register our dependency IEmployeeListing.

For this Sitecore has two ways:
Register dependencies in configuration:

<configuration>
    <sitecore>
        <services> 
            <register serviceType="IEmployeeListing, SCDemo.Web" implementationType="EmployeeListing, SCDemo.Web" />          
        </services>
    </sitecore>
</configuration>

We can register dependencies via code using a Configurator class, we implement the IServicesConfigurator as below:


public class RegisterDependencies : IServicesConfigurator
{
    public void Configure(IServiceCollection serviceCollection)
    {
        serviceCollection.AddTransient(typeof(IEmployeeService), typeof(EmployeeService));

    }
}

We can register these dependencies with different lifetimes such as AddTransient or AddScoped or AddSingleton.
Next we need to add configuration to register the RegisterDependencies  Configurator class as below:


<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
    <sitecore>
        <services>
            <configurator type="SCDemo.Web.ServiceConfigurator.RegisterDependencies,SCDemo.Web" />

        </services>
    </sitecore>
</configuration>

With built in IoC container we have few limitations when injecting dependency in controllers:

We may only have one public constructor for controller or any other registered dependency.

And controller class must be registered with the container to be resolvable (e.g. you must register it such as serviceCollection.AddTransient<EmployeeListingController>()).

What if we have too many Controllers to be registered ?
Option one would be to register each and every one.

Option two would be to use this extension class & register in bulk.

When we use the extension class, we can register out Controllers & services as below:


public class RegisterDependencies : IServicesConfigurator
{
    public void Configure(IServiceCollection serviceCollection)
    {
         serviceCollection.AddMvcControllers("*.SCDemo.Web.*");

        serviceCollection.AddTransient(typeof(IEmployeeService), typeof(EmployeeService));

    }
}

Here we are registering all the Controllers which has *SCDemo.Web.* in the namespace.
We can also add Extension methods to resolve service registration in bulk (hint : see Habitat solution).

 

What next? Try to setup DI in Sitecore Helix based solution.

Advertisements

Sitecore & DI – “Unable to resolve service for type …” Error

While I was setting up Dependency Injection in my Sitecore Helix solution, I was greeted with below YSOD :

Unable to resolve service for type 'SCDemo.Feature.Navigation.Repositories.INavRepo' while attempting to activate 'SCDemo.Feature.Navigation.Controllers.NavigationController'.

Unable to resolve service for type ‘SCDemo.Feature.Navigation.Repositories.INavRepo’ while attempting to activate ‘SCDemo.Feature.Navigation.Controllers.NavigationController’.

This is the Controller code:


public class NavigationController  :  Controller
{
    INavRepo _navRepo;

    public NavigationController (INavRepo navRepo)
    {
        _navRepo= navRepo;
    }

    // Action methods

}

Error message was load & clear – my service registration failed, so I started to look into the code which actually register these services.
I started to debug the Foundation project I’m having for Dependency Injection.
This Foundation project (or module) facilitate us to have single Composition Root by registering all the dependencies & Controllers using the Microsoft Dependency Injection Abstractions library. 

This Foundation project is replica of Sitecore Habitat’s Dependency project & it has one class “MvcControllerServicesConfigurator” which register services & Controllers:


public void Configure(IServiceCollection serviceCollection)
{
    serviceCollection.AddMvcControllers("*.Feature.*");
    serviceCollection.AddClassesWithServiceAttribute("*.Feature.*");
    serviceCollection.AddClassesWithServiceAttribute("*.Foundation.*");
}

The code above registers all the MVC Controllers which matches the *.Feature.* as well as services which matches *.Feature.* & *.Foundation.*.

This is done using an Extension class “ServiceCollectionExtensions” where these AddMvcControllers and AddClassesWithServiceAttribute methods along with few Helper methods are defined.

While looking into the this Extension class, I noticed that “AddClassesWithServiceAttribute” method is not getting any services for registration from Feature projects.


public static void AddClassesWithServiceAttribute(this IServiceCollection serviceCollection, params Assembly[] assemblies)
{
    var typesWithAttributes = assemblies
                              .Where(assembly => !assembly.IsDynamic)
                              .SelectMany(GetExportedTypes)
                              .Where(type => !type.IsAbstract && !type.IsGenericTypeDefinition)
                              .Select(type => new { type.GetCustomAttribute<ServiceAttribute>()?.Lifetime, ServiceType = type, ImplementationType = type.GetCustomAttribute<ServiceAttribute>()?.ServiceType })
                              .Where(t => t.Lifetime != null);

    foreach (var type in typesWithAttributes)
    {
        if (type.ImplementationType == null)
            serviceCollection.Add(type.ServiceType, type.Lifetime.Value);
        else
            serviceCollection.Add(type.ImplementationType, type.ServiceType, type.Lifetime.Value);
    }
}

This method uses reflection & filters all the classes with Service attribute, so any service which needs to be register must have the Service attribute.

What is this Service attribute?

This is a custom class, which inherit Attribute class & can be used as Attribute for other classes.


[AttributeUsage(AttributeTargets.Class, Inherited = false)]
public class ServiceAttribute : Attribute
{
    public ServiceAttribute()
    {

    }

    public ServiceAttribute(Type serviceType)
    {
        this.ServiceType = serviceType;
    }

    public Lifetime Lifetime { get; set; } = Lifetime.Singleton;
    public Type ServiceType { get; set; }
}

Here default Lifetime is used as Singleton, but you can use Transient Lifetime while defining the attribute.

All these classes are included with DI project I used from Sitecore Habitat.

I noticed  that I didn’t have Service attribute on my Repo class (which I wanted to register):


public class NavRepo : INavRepo
{
    public void DoStuff()
    {

        // Do stuff

    }

So I added the Service attribute to the implementation of INavRepo:


[Service(typeof(INavRepo))]
public class NavRepo : INavRepo
{
    public void DoStuff()
    {
        // Do stuff
    }
}

This way our service registration code in Foundation DI project will know that INavRepo is resolved with NavRepo class.
Everything worked after this, so if you are getting the same error, probably you forgot to add the Service Attribute.

Hope this will help.

Sitecore MVC For Beginners – Part 3 – View Rendering

After a very long long time, I’m back to writing blogs.

Sorry for the delayed part 3 of the blog series Sitecore MVC For Beginners.

In this post we will look into View Rendering in Sitecore MVC.

Before jumping into the View Rendering, let’s have some background about Sitecore renderings.

What are Sitecore renderings?
Well, Sitecore renderings are nothing but a way to render the content on the website pages.If you are aware of the Sublayouts in Sitecore, consider renderings similar to them (infect Sublayouts are also a type of renderings).
In MVC context, we can think rendering as Views, which drive the content to the users.

Where from the data comes?
We may often bind our Sitecore MVC renderings with a Model or we can utilize default Model.

How we associate these renderings to the items?
Based on the type of the rendering, these Sitecore renderings can be associated using MVC Controllers (e.g. Controller Renderings) or we can assign to the Presentation of the item (e.g. View Renderings).

Lets quickly have a look at the few of these rendering in Sitecore:
Go to the Renderings folder in Sitecore & see it’s insert options (right-click on the item & hover on Insert):
/sitecore/layout/Renderings

Sitecore MVC Renderings

As you can see we have different types of renderings here but we will be learning more about View Rendering & Controller rendering in this blog post.

For other types of rendering, please see the Sitecore Documentation.

View Rendering
View rendering is simplest of all available renderings & they are widely used.
Many times, View renderings work in a similar way the standard Sitecore sublayout works.

Let’s create a View Rendering but before that let’s create a folder item (based on the Renderings Folder template) under Renderings ( I named it MVC Demo).
We will use this folder to keep our renderings items.

Now right-click on this folder & using insert options, let’s create a View Rendering item.

insert_view_renderings

I named it Sample View Rendering.
Now let’s have a look at few of the important fields on View rendering item:

sample_view_rendering_item

Path: This fields is used to define the relative path of the associated .cshtml file (as we have .ascx for Sitecore sublayouts).
This .cshtml file represent the VIEW in terms of MVC terminology.

Area: We can use this field to declare the MVC Area.

Model: This field is used to select the Model item, from “/sitecore/layout/Models” & can be used to bind the View rendering to any specific Model instead of default Sitecore rendering model.

We will now create the associated .cshtml file in our VS Solution.

Let’s create the MVCDemo folder inside the Views folder and add an View:

 

Write the below code to use the default Sitecore RenderingModel as the Model for this view:

@model Sitecore.Mvc.Presentation.RenderingModel

Remember this would need the reference of SItecore.MVC dll in the project.

RenderingModel has Item property & this is the MVC representation (my personal thought) of SItecore.Context.Item which populate the few important properties such as item name, children & path etc.

If we define the datasource on the renering item in Sitecore, this would populate the DataSource item in the RenderingModel.Item property otherwise it will use the context item.

Now we will use this RenderingModel.Item to show the content of the “Title” field of context item.

For this, lets add below code in the View Rendering:
@Html.Sitecore().Field(“Title”)

Tip: Sitecore has many such helper extension methods available and to leverage best of the Sitecore one should use these.

For example when we use the above method, we can edit the field in the ExpereinceEditor.

Another Tip: If you don’t get the VS IntelliSense or get an error about the Sitecore not recognized as Html helper, make sure to define the below in web.config file in Views folder:

<add namespace=”Sitecore” />
<add namespace=”Sitecore.Mvc”/>
<add namespace=”Sitecore.Mvc.Presentation” />

Now let’s save the View Rendering & publish this new MVCDemo folder to the Views folder in web root(to keep it simple, let’s copy/paste the folder) .

Switch back to the Sitecore & navigate to the View rendering item we created.

We well provide the relative path of the .cshtml view in the Path field & this is how it is looking at my end:

Save & publish rendering item.

Next task is to set this View rendering on the Home item’s presentation.

I’ll skip the steps of adding the view rendering to the presentation of the Home item, but don’t forget to publish the item once you add it.
This is how the presentation layout looks like:

Navigate to the Home page & we should see the Title field is showing on the page.

 

Simple, isn’t it?

In next post, we will learn about the Sitecore Controller Rendering.

Sitecore MVC For Beginners – Part 1 – Getting Started

In recent times Sitecore MVC has gain much popularity & it has become a standard choice now.
With every new Sitecore release, this is becoming more popular & powerful.

I get more & more requests to write about Sitecore MVC so here it is, a blog series about Getting Started with Sitecore MVC for beginners like me.

In this blog series we will create a demo website while learning basics of Sitecore MVC.
Continue reading

Sitecore 8 – Experience Editor – HTML Formatting Getting Strip in Multiline Text Field

Few days back our client reported one issue where any formatting (HTML tags defined inside the MultiLine Text Field) were getting striped-out while saving the page in Experience Editor.

This was interesting as it was only happening in Experience Editor & If we save the page using Content Editor, everything was as expected.

Continue reading

View Sitecore Jobs – Sitecore SPEAK Module

This is the end product of all our learnings while I was writing the blog series Sitecore SPEAK for beginners.

As I said we should not only learn Sitecore SPAEK but make something useful for us.

I’ve packaged up all our learning into a Sitecore Module & published it to the Sitecore Market Place.

I named this “View Sitecore Jobs” & this module can be found here:
https://marketplace.sitecore.net:443/en/Modules/V/View_Sitecore_Jobs.aspx

Continue reading