c# - 最佳实践 : StructureMap and ASP. NET MVC 2 - 抽象基础 Controller 中的 Setter 注入(inject)/构造注入(inject)

标签 c# asp.net-mvc asp.net-mvc-2 structuremap setter

public abstract class ConventionController : Controller
{
    public const int PageSize = 5;

    public IMappingService MappingService { get; set;}
}

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

编辑:

Joshua Flanagan的帮助下,我现在有了以下代码:

员工 Controller

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

约定 Controller

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

如果我在 ConventionController 中使用构造函数,我会“污染”我的 EmployeeController(恕我直言)。

如果 EmployeeController 直接需要 IMapping 依赖项,我将使用构造函数进行注入(inject)。但这不是必需的,因为 ConventionController 已经有 IMapping 属性。所以正如Darin Dimitrov所说,这违反了 DI 原则。

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

编辑2

我如何命令 StructureMap 创建 HybridViewResult 的实例?如果这可能的话, Controller 就不需要知道 IMapping 依赖关系。是否有可能从 StructureMap 获取通用对象(未装箱)?

最佳答案

实际上,不,SetAllProperties() 不适用于抽象类。这是 Structuremap 实现中的一个弱点。我为你感到抱歉,就像我为自己感到抱歉一样,属性注入(inject)不适用于基本抽象类。对于基本抽象类,您将需要使用构造函数注入(inject)(与这里的所有炒作相反,这并不总是满足依赖关系时的最佳方法)。

关于c# - 最佳实践 : StructureMap and ASP. NET MVC 2 - 抽象基础 Controller 中的 Setter 注入(inject)/构造注入(inject),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3811402/

相关文章:

c# - iTextSharp 索引超出范围

c# - 为什么我会遇到名称冲突

c# - ASP.NET MVC 2 中具有一个名称的多个 Controller

c# - MVC 2 - 将枚举传递给 CheckBoxFor

asp.net-mvc - ASP.NET MVC 搜索路线

javascript - 如何从单页应用URL中解析参数?

c# - 如何在 C#.NET 的循环中创建不确定的后台线程

c# - jquery调用后如何刷新页面

c# - Web (MVC) 应用程序中的 AbotX 许可证文件不起作用

javascript - Uncaught ReferenceError : CustomerContract is not defined in Kendo Grid when creating new record