Service decorator

The Decorator design pattern follows the Open Closed Principle where 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 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".

Adding another decorator for the same service is possible, 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!".