Bestpractice DI与ASP.NET MVC和StructureMap - 如何在一个ActionResult注入依赖 [英] Bestpractice DI with ASP.NET MVC and StructureMap - How to inject dependencies in an ActionResult

查看:133
本文介绍了Bestpractice DI与ASP.NET MVC和StructureMap - 如何在一个ActionResult注入依赖的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我编辑我的整个问题,所以不要奇怪:)

I edited my whole question, so do not wonder :)

好吧,我想有一个的ActionResult 这需要域模型数据和一些额外的参数,即页面索引和页面大小分页列表。它决定自己是否会返回一个PartialViewResult或根据其种类Web请求(Ajax请求与否)的的ViewResult。

Well, I want to have an ActionResult that takes domain model data and some additional parameters, i.e page index and page size for paging a list. It decide itself if it returns a PartialViewResult or a ViewResult depending on the kind of web request (ajax request or not).

的下文称数据应通过使用IMappingService,它负责将任何域模型数据转换成一个视图模型自动映射。
该MappingService使用AutoMapper为简单起见。

The reffered data shall be mapped automatically by using an IMappingService, which is responsible for transforming any domain model data into a view model. The MappingService uses AutoMapper for simplicity.

MappingActionResult:

MappingActionResult:

public abstract class MappingActionResult : ActionResult
{
    public static IMappingService MappingService;
}

BaseHybridViewResult:

BaseHybridViewResult:

public abstract class BaseHybridViewResult : MappingActionResult
{
    public const string defaultViewName = "Grid";

    public string ViewNameForAjaxRequest { get; set; }
    public object ViewModel { get; set; }

    public override void ExecuteResult(ControllerContext context)
    {
        if (context == null) throw new ArgumentNullException("context");
        var usePartial = ShouldUsePartial(context);
        ActionResult res = GetInnerViewResult(usePartial);

        res.ExecuteResult(context);
    }

    private ActionResult GetInnerViewResult(bool usePartial)
    {
        ViewDataDictionary viewDataDictionary = new ViewDataDictionary(ViewModel);
        if (String.IsNullOrEmpty(ViewNameForAjaxRequest))
        {
            ViewNameForAjaxRequest = defaultViewName;
        }

        if (usePartial)
        {
            return new PartialViewResult { ViewData = viewDataDictionary, ViewName = ViewNameForAjaxRequest };
        }

        return new ViewResult { ViewData = viewDataDictionary };
    }

    private static bool ShouldUsePartial(ControllerContext context)
    {
        return context.HttpContext.Request.IsAjaxRequest();
    }
}

AutoMappedHybridViewResult:

AutoMappedHybridViewResult:

public class AutoMappedHybridViewResult<TSourceElement, TDestinationElement> : BaseHybridViewResult
{
    public AutoMappedHybridViewResult(PagedList<TSourceElement> pagedList)
    {
        ViewModel = MappingService.MapToViewModelPagedList<TSourceElement, TDestinationElement>(pagedList);
    }

    public AutoMappedHybridViewResult(PagedList<TSourceElement> pagedList, string viewNameForAjaxRequest)
    {
        ViewNameForAjaxRequest = viewNameForAjaxRequest;
        ViewModel = MappingService.MapToViewModelPagedList<TSourceElement, TDestinationElement>(pagedList);
    }

    public AutoMappedHybridViewResult(TSourceElement model)
    {
        ViewModel = MappingService.Map<TSourceElement, TDestinationElement>(model);
    }

    public AutoMappedHybridViewResult(TSourceElement model, string viewNameForAjaxRequest)
    {
        ViewNameForAjaxRequest = viewNameForAjaxRequest;
        ViewModel = MappingService.Map<TSourceElement, TDestinationElement>(model);
    }
}

在控制器用法:

public ActionResult Index(int page = 1)
{
    return new AutoMappedHybridViewResult<TeamEmployee, TeamEmployeeForm>(_teamEmployeeRepository.GetPagedEmployees(page, PageSize));
}

因此​​,大家可以看到 IMappingService 是隐藏的。控制器不应该知道关于 IMappingService 接口,当 AutoMappedHybridViewResult 用于任何东西。

So as you can see the IMappingService is hidden. The controller should not know anything about the IMappingService interface, when AutoMappedHybridViewResult is used.

MappingActionResult 静态IMappingServer 适当的还是我违反原则DI

Is the MappingActionResult with the static IMappingServer appropriate or am I violating the DI principle?

推荐答案

我觉得更好的设计是有依赖于IMappingService一个ViewResultFactory,那么你可以注入该到控制器。然后调用它像这样:

I think a better design is to have a ViewResultFactory that depends on IMappingService, then you can inject that into your controller. Then you call it like so:

public class MyController : Controller
{
    IViewResultFactory _viewResultFactory;
    ITeamEmployeeRepository _teamEmployeeRepository;

    public MyController(IViewResultFactory viewResultFactory)
    {
        _viewResultFactory = viewResultFactory;
    }

    public ActionResult MyAction(int page, int pageSize)
    {
        return
            _viewResultFactory.GetResult<TeamEmployee, TeamEmployeeForm>(
                _teamEmployeeRepository.GetPagedEmployees(page, pageSize));
    }
}

的实施将是这样的(你需要为每个HybridViewResult构造函数重载创建):

The implementation would like this (you would need to create overloads for each of your HybridViewResult constructors):

public HybridViewResult<TSourceElement, TDestinationElement> GetResult<TSourceElement, TDestinationElement>(PagedList<TSourceElement> pagedList)
{
    return new HybridViewResult<TSourceElement, TDestinationElement>(_mappingService, pagedList);
}

这样,你隐藏你的控制器的实现,你不必依赖于容器。

That way you hide the implementation from your controllers, and you don't have to depend on the container.

这篇关于Bestpractice DI与ASP.NET MVC和StructureMap - 如何在一个ActionResult注入依赖的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆