I’m tring to create a class which does all sorts of low-level database-related actions but presents a really simple interface to the UI layer.
This class represents a bunch of data all within a particular aggregate root, retrieved by a single ID int.
The constructor takes four parameters:
public AssetRegister(int caseNumber, ILawbaseAssetRepository lawbaseAssetRepository, IAssetChecklistKctcPartRepository assetChecklistKctcPartRepository, User user)
{
_caseNumber = caseNumber;
_lawbaseAssetRepository = lawbaseAssetRepository;
_assetChecklistKctcPartRepository = assetChecklistKctcPartRepository;
_user = user;
LoadChecklists();
}
The UI layer accesses this class through the interface IAssetRegister. Castle Windsor can supply the ILawbaseAssetRepository and IAssetChecklistKctcPartRepository parameters itself, but the UI code needs to supply the other two using an anonymous type like this:
int caseNumber = 1000;
User user = GetUserFromPage();
IAssetRegister assetRegister = Moose.Application.WindsorContainer.Resolve<IAssetRegister>(new { caseNumber, user});
From the API design point of view, this is rubbish. The UI layer developer has no way of knowing that the IAssetRegister requires an integer and a User. They need to know about the implementation of the class in order to use it.
I know I must have some kind of design issue here. Can anyone give me some pointers?
As Morten points out, move the non injectable dependecies from the constructor call to the method(s) that actually need to use it,
If you have constructor paramters that can’t (or are difficult to) be injected you won’t be able to autmatically inject
IAssetRegisterinto any class that needs it either.You could always, of course, create a
IUserProviderinterface with a concrete implementation along these lines:Thus creating another injectable dependency where there was none. Now you eliminate the need to pass a user to every method that might need it.