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允许您定义应该注入的属性的条件。

10-04 22:30