Service decorator

The Decorator design pattern follows the open/closed principle, which means classes are designed as open for extensions but closed for modifications.

With service decorator, it is possible to extend the functionality for a service without touching the implementation.

Example service:

[Litium.Runtime.DependencyInjection.Service(
    ServiceType = typeof(IMyService), 
    Lifetime = Litium.Runtime.DependencyInjection.DependencyLifetime.Transient)]
public interface IMyService
{
    string MyMethod(); // define the service contract members
}
 
internal class MyServiceImpl : IMyService
{
    public string MyMethod()
    {
        return "world";
    }
}

Usage:

public class DependencyInjectionExample
{
    private readonly IMyService _myService;
 
    public DependencyInjectionExample(IMyService myService)
    {
        _myService = myService;
    }
 
    public void Method()
    {
        string result = _myService.MyMethod();
    }
}

When executing the Method() in the above example the result variable will contain the string "world".

A service decorator is an implementation class that is implementing the contract (abstract class or interface) and is registered with the Litium.Runtime.DependencyInjection.ServiceDecorator attribute.

In the constructor for the service decorator implementation, it is possible to inject the service that is decorated. Example:

[Litium.Runtime.DependencyInjection.ServiceDecorator(typeof(IMyService))]
internal class MyService1Decorator : IMyService
{
    private IMyService _parent;
    public MyService1Decorator(IMyService parent){
        _parent = parent; // impl instance of type MyServiceImpl
    }
    public string MyMethod()
    {
        return "Hello " + _parent.MyMethod();
    }
}

Executing the above example again will set the result variable to "Hello world".

It is possible to add another decorator for the same service. The decorators will be chained together.

[Litium.Runtime.DependencyInjection.ServiceDecorator(typeof(IMyService))]
internal class MyService2Decorator : IMyService
{
    private IMyService _parent;
    public MyService2Decorator(IMyService parent){
        _parent = parent; // impl instance of type MyService1Decorator
    }
    public string MyMethod()
    {
        return _parent.MyMethod() + "!";
    }
}

Executing the above example again will set the result variable to "Hello world!".