arielorvits
arielorvits

Reputation: 5535

asp.net core build-in dependency injection long code

In our previous app we used StructureMap and we could write very little code.

before every service we added the dependencies like:

[SetterProperty]
public IXService XService { get; set; }

and in the constructor

ObjectFactory.BuildUp(this);

then in test we could instantiate it simply by

var service = new XService();

Now, we start another app and using asp.net core build-in DI container. it look like we should write a lot of code, and very long constructor for each test:

    private readonly ILogger<AccountsController> _logger;
    private readonly IMapper _mapper;
    private readonly IAccountBlService _accountBlService;
    private readonly IValidationHelper _validationHelper;
    private readonly IValidator<AccountDTO> _accountDTOValidator;
    private readonly Example _example;
    private readonly IConfiguration _configuration;

    public AccountsController(BillingContext context, ILogger<AccountsController> logger, IMapper mapper, IAccountBlService accountBlService, 
        IValidationHelper validationHelper, IValidator<AccountDTO> accountDTOValidator, IOptions<Example> example, IConfiguration configuration)
    {
        _logger = logger;
        _mapper = mapper;
        _accountBlService = accountBlService;
        _validationHelper = validationHelper;
        _accountDTOValidator = accountDTOValidator;
        _configuration = configuration;
        _example = example.Value;
    }

Is there a shorter way we didnt found? is one planned for the near future? should we use StructureMap instead the built-in container? or there are disadvantages for this? thanks!

Upvotes: 1

Views: 122

Answers (1)

Danny van der Kraan
Danny van der Kraan

Reputation: 5366

  • Is there a shorter way we didnt found? In short: No, not with the default container. But I recommend you read Dependency Injection in .NET by Mark Seemann (if you have then please ignore me saying this), because have you heard of "Composition Root"? IMHO the way you declared dependencies has the same amount of code, just scattered all over your code base. While you should really keep it in one place for maintainability.
  • Is one planned for the near future? Not that I know of, but really if you look at it, it's the same amount of code, just centralized. We however use NServiceBus's ability to call "RegisterComponents" on the BusConfiguration which uses reflection to register all dependencies in one call. You could look for containers that can do the same. Now if you're thinking about your tests, if you use XUnit you can set up your SUT via de test class's constructor. Refactor it in factory classes so you only have to write it once. This way you can also throw mocks in to keep your tests clean.
  • Should we use StructureMap instead the built-in container? If you wish. We use Autofac.
  • Or are there disadvantages for this? Not that we've encountered thus far. Sometimes you need the IServiceProvider for special 'tricks' but there's always a way.

Note: if you are concerned about having 7 dependencies in your controller (which is a lot indeed) there are a few options:

  • Look at the scope of the dependency. If it's only used in 1 or 2 action methods you can also declare it [FromService] in the action method's signature

  • Is your controller doing too much? Watch out for god classes. Maybe it needs refactoring. After all, controllers are nothing more than logical collections of action methods.

  • Can dependencies be combined? Sometimes it seems they need to be seperated, but in most contexts they are always in pairs. It appears there's a high cohesion and you could combine them in a helper class to maintain cohesion.

Upvotes: 5

Related Questions