3

Traditionally, we register multiple services, multiple interfaces under ConfigureServices method in the Startup class. This is feasible if we have five or ten registrations. But what if we have fifty or more such registrations?

public void ConfigureServices(IServiceCollection services) {
  service.AddTransient<ISQLDB, SQLDB>();
  service.AddTransient<IEmployeeBusiness, EmployeeBusiness>();
  service.AddTransient<IEmployeeRepository, EmployeeRepository>();
  service.AddTransient<IEmployeeValidation, EmployeeValidation>();
  service.AddTransient<IDepartmentBusiness, DepartmentBusiness>();
  service.AddTransient<IDepartmentRepository, EmployeeRepository>();
  service.AddTransient<IDepartmentValidation, EmployeeValidation>();
  ...
  ...
  ...
  // some 50 or more
}
    

I want to move the registering part to another custom InjectDependency class and call this in ConfigureServices method like:

public class InjectDependency{
    public InjectDependency(IServiceCollection service)
    {
      service.AddTransient<ISQLDB, SQLDB>();
      service.AddTransient<IEmployeeBusiness, EmployeeBusiness>();
      service.AddTransient<IEmployeeRepository, EmployeeRepository>();
      service.AddTransient<IEmployeeValidation, EmployeeValidation>();
      service.AddTransient<IDepartmentBusiness, DepartmentBusiness>();
      service.AddTransient<IDepartmentRepository, EmployeeRepository>();
      service.AddTransient<IDepartmentValidation, EmployeeValidation>();
      ...
      ...
      ...
      ...
    }
  }

Is there any way to achieve this?

2
  • 1
    What isn't working with your code? Since you're passing your IServiceCollection reference to your InjectDependency class, this should work just fine. Are you receiving an error? Are you just not sure how to call this? Note that since this is a stateless function, it may make more sense to treat it as a static method rather than a constructor. Commented Nov 13, 2020 at 20:49
  • Thanks. It worked by using extension methods Commented Nov 14, 2020 at 11:37

1 Answer 1

2

Your code should work fine as is, though there are a couple of improvements you could make.

First, your InjectDependency() constructor is essentially stateless, so it would make more sense as a static method rather than a constructor. Second, to take that one step further, you could set it up as an extension method off of the IServiceCollection interface, which is a really common approach to this scenario:

public class ServiceCollectionExtensions {
  public static IServiceCollection AddBusinessLogic(this IServiceCollection services) {
    services.AddTransient<ISQLDB, SQLDB>();
    services.AddTransient<IEmployeeBusiness, EmployeeBusiness>();
    services.AddTransient<IEmployeeRepository, EmployeeRepository>();
    …    
    return services;
  }
}

Then, in your Startup class, you'd simply call this like:

public void ConfigureServices(IServiceCollection services) {
  services.AddBusinessLogic();
}

If you have that many implementations, however, you might also try to determine if there's a common pattern or convention you can use to dynamically register them. For example, in your sample data, a lot of your implementations share the same base identifier as the interface. If that pattern holds, it might be easier to write code that automates that. There's a good example of this on the question Built-in dependency injection with conventions.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks using extension method it worked. Here is full implementation
I don't see any option to mark your response as Answer. How do I mark the response as Answer?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.