Ian Jowett
Ian Jowett

Reputation: 324

Service Wrapper => Service Pattern best practices

I am build a enterprise level web api from the ground up, I have around 12 services and a entity framework repo wrapper.

Basically after a refactor of my web api, I realised I was passing 9 services into the controller via IOC.

So I have created a service wrapper for all my services:

public class ServiceWrapper : IServiceWrapper
    {
        public ServiceWrapper(ILoggerManager loggerManager, IRepositoryWrapper repositoryWrapper, IAuditLog auditLog, IConfiguration config, ICsvImporter csvImporter, IEmailService emailService, IEmailTemplate emailTemplate, IEmailConfiguration emailConfig, IEncoreService encoreService, IUserService userService, ISQLClient sqlClient, IDocumentService documentService)
        {
            LoggerManager = loggerManager;
            RepositoryWrapper = repositoryWrapper;
            AuditLog = auditLog;
            Config = config;
            CsvImporter = csvImporter;
            EmailService = emailService;
            EmailTemplate = emailTemplate;
            EncoreService = encoreService;
            UserService = userService;
            EmailConfiguration = emailConfig;
            SqlClient = sqlClient;
            DocumentService = documentService;
        }

        public ILoggerManager LoggerManager { get; set; }       
        public IRepositoryWrapper RepositoryWrapper { get; set; }
        public IAuditLog AuditLog { get; set; }
        public IConfiguration Config { get; set; }
        public ICsvImporter CsvImporter { get; set; }
        public IEmailService EmailService { get; set; }
        public IEmailConfiguration EmailConfiguration { get; set; }
        public IEmailTemplate EmailTemplate { get; set; }
        public IEncoreService EncoreService { get; set; }
        public IUserService UserService { get; set; }
        public ISQLClient SqlClient { get; set; }
        public IDocumentService DocumentService { get; set; }
    }

My question really, is this best practice, or is there a better way, I want to stay with domain driven architecture, IOC and service patterns.

Thanks

Upvotes: 1

Views: 1031

Answers (1)

Vyacheslav Benedichuk
Vyacheslav Benedichuk

Reputation: 387

The service wrapper is very ineffective as your app instantiate all the services on every api call, even if these services won't be used.

To reduce amount of services passed via constructor or api methods signatures you can pass IService provider and use GetService extension method.

In this case you will be able to instantiate only the necessary services when you'll need it.

In most cases the code won't be more compex than with service wrapper. If it won't be sufficient you can update your wrapper in following way:

public class ServiceWrapper : IServiceWrapper
{
    private readonly IServiceProvider _serviceProvider;
    public ServiceWrapper(IServiceProvider serviceProvider)
    {
        _serviceProvider = serviceProvider;
    }
    
    public ILoggerManager LoggerManager { get { return _serviceProvider.GetService<ILoggerManager>(); }} // store GetService result in a local property if it will be necessary for reuse.
    ....

}

But I don't recommend this approach as it increase components coupling and may reduce app maintainability in the future.

Upvotes: 1

Related Questions