Monthly Archives: July 2020

Software Patterns and Philosophies: Usage of a container facade

The problem

I was working with a relational data model which we denomarlized to be stored in Elasticsearch for searching purposes. While implementing a mechanism to stream changes from the underlying data sources into Elasticsearch, we had some choices to make on the underlying persistence.

While creating a POC to validate some assumptions, I found myself with a class, let’s call this thing a master builder, taking too many dependencies into its constructor like this:

        public class IdentityModelBuilder : CompositeModelBuilder<Identity>
    {
        private readonly IIdentityRepository _identityRepository;
        private readonly ISourceRepository _sourceRepository;
        private readonly IAccountRepository _accountRepository;
        private readonly IAccessProfileRepository _accessProfileRepository;
        private readonly IIdentityProfileRepository _identityProfileRepository;
        private readonly IRoleRepository _roleRepository;
        private readonly IEntitlementRepository _entitlementRepository;
        private readonly ITagsRepository _tagsRepository;
        private readonly IApplicationRepository _applicationRepository;
        private readonly IGovernanceGroupRepository _governanceGroupRepository;
        private readonly IAttributesRepository _attributesRepository;

        public IdentityModelBuilder(
            ISourceRepository sourceRepository,
            IAccountRepository accountRepository,
            IIdentityRepository identityRepository,
            IIdentityProfileRepository identityProfileRepository,
            IAccessProfileRepository accessProfileRepository,
            IRoleRepository roleRepository,
            IEntitlementRepository entitlementRepository,
            ITagsRepository tagsRepository,
            IApplicationRepository applicationRepository,
            IGovernanceGroupRepository governanceGroupRepository = null,
            IAttributesRepository attributesRepository = null)
        {
            _sourceRepository = sourceRepository;
            _identityRepository = identityRepository;
            _identityProfileRepository = identityProfileRepository;
            _accountRepository = accountRepository;
            _accessProfileRepository = accessProfileRepository;
            _roleRepository = roleRepository;
            _entitlementRepository = entitlementRepository;
            _tagsRepository = tagsRepository;
            _applicationRepository = applicationRepository;
            _governanceGroupRepository = governanceGroupRepository;
            _attributesRepository = attributesRepository;
        }

      //.. 
        protected override IList<IPropertyAssigner> EstablishSubContractors()
        {
            return new List<IPropertyAssigner>
            {
                new SourceAssigner(_sourceRepository),
                new IdentityProfileSummaryAssigner(_identityProfileRepository),
                new ManagerSummaryAssigner(_identityRepository),
               
                // ... omitted for brevity
            };
        }
    }
}

Usage of all these dependencies is not a concern as we are mostly delegating construction of parts of the Identity model to these subcontractors (assigners). However, the constructor makes me cringe, as it appears to violate certain aspects of the SOLID principles and also makes it difficult to use this builder within a context where we do not have all these dependencies: users will also have to modify their constructors to depend on all these artifacts. And this just propagates upstream!

The Solution

While I believe on passing dependencies explicitly from a code readability and testability perspective (not a fan of private member injection), this is one area where I believe one can leverage a construct such as a container facade to pass in these dependencies as follows:

   public IdentityModelBuilder(IContainerFacade containerFacade) : this (
            containerFacade.Resolve<ISourceRepository>(),
            containerFacade.Resolve<IAccountRepository>(),
            containerFacade.Resolve<IIdentityRepository>(),
            containerFacade.Resolve<IIdentityProfileRepository>(),
            containerFacade.Resolve<IAccessProfileRepository>(),
            containerFacade.Resolve<IRoleRepository>(),
            containerFacade.Resolve<IEntitlementRepository>(),
            containerFacade.Resolve<ITagsRepository>(),
            containerFacade.Resolve<IApplicationRepository>(),
            containerFacade.Resolve<IGovernanceGroupRepository>())
        {
        }

// second constructor omitted for brevity

Where the container interface is:

  public interface IContainerFacade
    {
        T Resolve<T>();
    }

This simple change allows one to use master builder in a context where do you do not have all those dependencies but do have access to the IContainerFacade.