Bestpractice DI与ASP.NET MVC和StructureMap - 如何在一个ActionResult注入依赖 [英] Bestpractice DI with ASP.NET MVC and StructureMap - How to inject dependencies in an 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屋!