public abstract class ConventionController : Controller
{
public const int PageSize = 5;
public IMappingService MappingService { get; set;}
}
如何设置StructureMap以获取IMappingService的实例?
编辑:
在Joshua Flanagan的帮助下,我现在有以下代码:
EmployeeController
public class EmployeeController : ConventionController
{
private readonly ITeamEmployeeRepository _teamEmployeeRepository;
public EmployeeController(ITeamEmployeeRepository teamEmployeeRepository)
{
_teamEmployeeRepository = teamEmployeeRepository;
}
public ActionResult Index(int page = 1)
{
// The IMappingService dependency is hidden in the AutoMappedHybridView method that is a part of the ConventionController, easy use in the controller
return AutoMappedHybridView<TeamEmployee, TeamEmployeeForm>(_teamEmployeeRepository.GetPagedEmployees(page, PageSize));
// With constructor injection I had to write this ...
// return new HybridViewResult<TSourceElement, TDestinationElement>(_mappingService, _teamEmployeeRepository.GetPagedEmployees(page, PageSize));
}
}
ConventionController
public abstract class ConventionController : Controller
{
public const int PageSize = 5;
// This property is inject via StructureMap
public IMappingService MappingService { get; private set; }
public HybridViewResult<TSourceElement, TDestinationElement> AutoMappedHybridView<TSourceElement,TDestinationElement>(PagedList<TSourceElement> pagedList, string viewNameForAjaxRequest)
{
return new HybridViewResult<TSourceElement, TDestinationElement>(MappingService, pagedList, viewNameForAjaxRequest);
}
public HybridViewResult<TSourceElement, TDestinationElement> AutoMappedHybridView<TSourceElement,TDestinationElement>(PagedList<TSourceElement> pagedList)
{
return new HybridViewResult<TSourceElement, TDestinationElement>(MappingService, pagedList);
}
public HybridViewResult<TSourceElement, TDestinationElement> AutoMappedHybridView<TSourceElement, TDestinationElement>(TSourceElement sourceElement)
{
return new HybridViewResult<TSourceElement, TDestinationElement>(MappingService, sourceElement);
}
public HybridViewResult<TSourceElement, TDestinationElement> AutoMappedHybridView<TSourceElement, TDestinationElement>(TSourceElement sourceElement, string viewNameForAjaxRequest)
{
return new HybridViewResult<TSourceElement, TDestinationElement>(MappingService, sourceElement, viewNameForAjaxRequest);
}
}
HybridViewResult
public class HybridViewResult<TSourceElement, TDestinationElement> : BaseHybridViewResult
{
public HybridViewResult(IMappingService mappingService, PagedList<TSourceElement> pagedList)
{
ViewModel = mappingService.MapToViewModelPagedList<TSourceElement, TDestinationElement>(pagedList);
}
public HybridViewResult(IMappingService mappingService, PagedList<TSourceElement> pagedList, string viewNameForAjaxRequest)
{
ViewNameForAjaxRequest = viewNameForAjaxRequest;
ViewModel = mappingService.MapToViewModelPagedList<TSourceElement, TDestinationElement>(pagedList);
}
public HybridViewResult(IMappingService mappingService, TSourceElement model)
{
ViewModel = mappingService.Map<TSourceElement, TDestinationElement>(model);
}
public HybridViewResult(IMappingService mappingService, TSourceElement model, string viewNameForAjaxRequest)
{
ViewNameForAjaxRequest = viewNameForAjaxRequest;
ViewModel = mappingService.Map<TSourceElement, TDestinationElement>(model);
}
}
如您所见,HybridViewResult需要IMappingService依赖项。
如果我在ConventionalController中使用构造函数,则会“污染”我的EmployeeController(imho)。
如果EmployeeController直接需要IMapping依赖关系,我将使用构造函数进行注入。但这不是必需的,因为ConventionController已经具有IMapping属性。因此,正如达林·迪米特洛夫(Darin Dimitrov)所说,这将违反直接投资原则。
如何重构代码?我真的必须使用构造函数注入吗?
编辑2
如何订购StructureMap创建HybridViewResult的实例?如果可能的话,控制器将不需要了解IMapping依赖关系。是否可以从StructureMap获取通用对象(未装箱)?
最佳答案
我假设您已经将控制器从StructureMap中删除。如果是这种情况,您只需要将SetAllProperties()
调用添加到容器配置中。 SetAllProperties允许您定义应该注入的属性的条件。