代码之家  ›  专栏  ›  技术社区  ›  Rookian

最佳实践:结构图和ASP.NET抽象基控制器中的mvc2-Setter注入/结构注入

  •  2
  • Rookian  · 技术社区  · 14 年前
    public abstract class ConventionController : Controller
    {
        public const int PageSize = 5;
    
        public IMappingService MappingService { get; set;}
    }
    

    如何设置StructureMap来获取IMappingService的实例?

    在…的帮助下 约书亚·弗拉纳根 我现在有以下代码:

    员工控制员

    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));
        }
     }
    

    约定控制员

    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);
        }
    }
    

    杂交结果

    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依赖项。

    如果EmployeeController直接需要IMapping依赖项,我将使用构造函数进行注入。但这不是必需的,因为ConventionController已经有IMapping属性。所以

    如何重构代码?我真的必须使用构造函数注入吗?

    编辑2

    我如何命令StructureMap创建HybridViewResult的实例?如果这是可能的,控制器就不需要知道IMapping依赖关系。有没有可能从StructureMap中得到一个通用对象(不是装箱的)?

    2 回复  |  直到 14 年前
        1
  •  1
  •   Joshua Flanagan    14 年前

    我假设您已经将控制器从StructureMap中取出。如果是这样的话,您只需要添加 SetAllProperties()

        2
  •  2
  •   Bob    13 年前

    实际上,不,SetAllProperties()会 为抽象类工作。这是Structuremap实现中的一个弱点。我很抱歉,就像我自己一样,属性注入对基抽象类不起作用。对于基本抽象类,您将需要使用构造函数注入(与这里所有的宣传相反,在满足依赖性时,构造函数注入并不总是最好的方式)。