I\'ve recently got a task to create a simple utility that allows to import data from a file with special format to the database. I\'ve implemented console application with f
I need to create an interface and implement it in the data access class. Also I will have to add a constructor to the business logic class that will accept parameter of that interface type. So this means that I will end up creating data access class in the application Main() method and something tells me this not the best approach (is it really ok that the entry point should know about some data access things? what if the chain is much longer or there should be several chains?)
On the contrary! This is the best approach, at least from a testability perspective.
The only way to make your business logic layer testable is to isolate it from your data access layer by doing exactly what you're contemplating.
Your top-level application is where the buck stops - it's the only component that should need to know what the concrete data access class is.
If the chain is much longer or there are several chains, that's no big deal (though you may want to consider collapsing some application layers if it gets out of hand). Consider this potential code in a Model-View-Presenter
app's View
, where the Presenter
has a dependency on a CustomerService
, which has a dependency on a Repository
and a dependency on an AccountingService
(which is also dependent on the Repository
):
public CustomerView() {
IRespository repository = new ConcreteRepository();
IAccountingService accountingService = new ConcreteAccountingService(repository);
ICustomerService customerService = new ConcreteCustomerService(accountingService, repository)
this._Presenter = new CustomerPresenter(customerService);
}
Finally, there's no need to use a dependency injection container if you don't want to (though some of them are surprisingly lightweight) - dependency injection by hand works fine until you start repeating yourself all over the place (or find you want to configure the dependencies at runtime).