Using Autofac Aggregate Services

September 13, 2016

no comments

I really like using Autofac, it’s one of the most productive libraries I know, and it’s so much fun to discover new features.

Aggregate Services is Autofac feature that allows you to wrap a set of dependencies into a single aggregate without the need to implement a concrete type for it.

Consider the following case where you have a base class that has dependencies on a few other services, and two derived classes:

class BaseLicenseGenerator:ILicenseGenerator
{
    //members

    public BaseLicenseGenerator(ILogger logger, IUserRepository userRepository, ILicenseRepository licenseRepository)
    {
        _logger = logger;
        _userRepository = userRepository;
        _licenseRepository = licenseRepository;
    }
        
    //...
}

class PerMonthLicenseGenerator 
    : BaseLicenseGenerator
{
    public PerMonthLicenseGenerator(ILogger logger, IUserRepository userRepository, ILicenseRepository licenseRepository)
        : base(logger, userRepository, licenseRepository)
    {
    }

    //...
}

class YearlyLicenseGenerator : BaseLicenseGenerator
{
    public YearlyLicenseGenerator(ILogger logger, IUserRepository userRepository, ILicenseRepository licenseRepository)
        : base(logger, userRepository, licenseRepository)
    {
    }

    //...
}

 

To me, the need to include all the dependencies of the base class inside the derived classes constructor is a little counter-productive. If I need to make a change to the dependencies of the base class, I’ll have to go and modify the derived classes as well.

With Autofac Aggregate Services, I can change the base class to include a single dependency which will wrap all the other dependencies together.
All I need is to add reference to the Autofac.Extras.AggregateService nuget package.

public interface ILicenseGeneratorDependencies
{
    ILogger Logger { get; }
    IUserRepository UserRepository { get; }
    ILicenseRepository LicenseRepository { get; }
}

Now I just need to register this interface to my container as an aggregate service and change my classes to use it.

var containerBuilder = new ContainerBuilder();
containerBuilder.RegisterType().As();
containerBuilder.RegisterType().As();
containerBuilder.RegisterType().As();
containerBuilder.RegisterType().AsSelf();

containerBuilder.RegisterAggregateService();

class BaseLicenseGenerator : ILicenseGenerator
{
    //members
    
    public BaseLicenseGenerator(ILicenseGeneratorDependencies licenseGeneratorDependencies)
    {
        _logger = licenseGeneratorDependencies.Logger;
        _userRepository = licenseGeneratorDependencies.UserRepository;
        _licenseRepository = licenseGeneratorDependencies.LicenseRepository;
    }
    
    //...
}

class PerMonthLicenseGenerator
    : BaseLicenseGenerator
{
    public PerMonthLicenseGenerator(ILicenseGeneratorDependencies licenseGeneratorDependencies)
        : base(licenseGeneratorDependencies)
    {
    }

    //...
}

 

that’s it! now if I need to change the BaseLicenseGenerator class and add a dependency, I just need to change the ILicenseGeneratorDependencies interface, and leave the derived classes untouched

Add comment
facebook linkedin twitter email

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*