The main impetus for this review is to determine if my ASP.NET Web API controller has too many dependencies. I'm of the opinion that 3-4 is okay, but 6 seems like too many. I have many controllers with similar layout. I've considered extracting all of the "PostPrimary" operations into a single wrapping dependency, but not sure if that's overkill. If I did create a wrapper, I'm not sure whether I'd create some IManipulator
interface and the wrapper could just hold its own IEnumerable<IManipulator>
that it could iterate through and execute each, or whether It would just explicitly hold one of each dependency.
Some other things to note:
- This particular controller only has one "PrePrimary" manipulator, though similar controllers have more, so a PrePrimary wrapper would also be a possibility.
- I'd prefer to use some ORM instead of the repository pattern, but this legacy database is so messed up, NHibernate struggled to navigate my last project through the swamp of SQL, but the going was slow and they got bogged down many times.
- I understand that my repository's method contains waaay too many parameters, but I feel like a repository should be fairly open and honest about what constraints its going to use in its SQL, so I use a 1:1 relationship between repository parameters and SQL parameters that go into the
WHERE
clause. Is this reasonable? - The verbosity of my identifiers is not open for discussion :P
So with that,
using System.Web.Http;
using MyProject.Models;
using MyProject.Models.DtoV1;
using MyProject.Models.Repo;
namespace MyProject.Controllers.Version1
{
public class PropertyDimensionController : ApiController
{
private readonly IPropcodeVetter propcodeVetter;
private readonly IPropertyDimensionRepository propertyDimensionRepository;
private readonly IPropertyDimensionAllPropsManager propertyDimensionAllPropsManager;
private readonly IComparisonRundateVsPopulator comparisonRundateVsPopulator;
private readonly IMetricBenchRatePopulator metricBenchRatePopulator;
private readonly IDecimalRounder decimalRounder;
public PropertyDimensionController(IPropertyDimensionRepository propertyDimensionRepository, IPropcodeVetter propcodeVetter,
IPropertyDimensionAllPropsManager propertyDimensionAllPropsManager, IMetricBenchRatePopulator metricBenchRatePopulator,
IComparisonRundateVsPopulator comparisonRundateVsPopulator, IDecimalRounder decimalRounder)
{
this.propertyDimensionRepository = propertyDimensionRepository;
this.propcodeVetter = propcodeVetter;
this.propertyDimensionAllPropsManager = propertyDimensionAllPropsManager;
this.metricBenchRatePopulator = metricBenchRatePopulator;
this.comparisonRundateVsPopulator = comparisonRundateVsPopulator;
this.decimalRounder = decimalRounder;
}
public PropertyDimensionResponse Post(PropertyDimensionRequest propertyDimensionRequest)
{
// PropertyDimension's PrePrimary Manipulations
var vettedPropcodes = propcodeVetter.GetVettedPropcodes(propertyDimensionRequest);
// PropertyDimension's Primary Operation
var propertyDimensionResponse = propertyDimensionRepository.Read(propertyDimensionRequest.Clientcode,
propertyDimensionRequest.Projectcode, vettedPropcodes, propertyDimensionRequest.Rundate,
propertyDimensionRequest.ComparisonRundate, propertyDimensionRequest.DemographicResponse,
propertyDimensionRequest.Metric, propertyDimensionRequest.MetricOnly);
// PropertyDimension's PostPrimary Manipulations
propertyDimensionResponse = propertyDimensionAllPropsManager.EnsureAllProperties(propertyDimensionResponse, propertyDimensionRequest);
propertyDimensionResponse = comparisonRundateVsPopulator.Populate(propertyDimensionResponse);
propertyDimensionResponse = metricBenchRatePopulator.Populate(propertyDimensionResponse);
propertyDimensionResponse = decimalRounder.RoundAllValues(propertyDimensionResponse);
return propertyDimensionResponse;
}
}
}