Asp.net mvc asp.net mvc控制器构造函数中的多个依赖项
在我的asp.net mvc控制器的构造函数中,我有多(5)个接口,它们通过以下方式与我的数据库通信:Asp.net mvc asp.net mvc控制器构造函数中的多个依赖项,asp.net-mvc,model-view-controller,dependency-injection,controller,Asp.net Mvc,Model View Controller,Dependency Injection,Controller,在我的asp.net mvc控制器的构造函数中,我有多(5)个接口,它们通过以下方式与我的数据库通信: [HttpGet] public ActionResult Create() { var releases = _releaseDataProvider.GetReleases(); var templates = _templateDataProvider.GetTemplates(); var createTestplanViewModel = new Creat
[HttpGet]
public ActionResult Create()
{
var releases = _releaseDataProvider.GetReleases();
var templates = _templateDataProvider.GetTemplates();
var createTestplanViewModel = new CreateTestplanViewModel(templates, releases);
return PartialView(createTestplanViewModel);
}
上面我使用了两个不同的接口从数据库中获取数据
业务案例:要创建一个测试计划,我需要向用户显示可用的版本+模板,用户可以从中选择
如何减少这两个接口的依赖性/过度注入编辑
在我看来,您基本上有以下选项来减少构造函数依赖项计数:
这与我的建议大致相同:
public interface IProvideTestPlanSetupModel
{
CreateTestplanViewModel GetModel();
}
public class TestPlanSetupProvider : IProvideTestPlanSetupModel
{
private readonly IReleaseDataProvider _releaseDataProvider;
private readonly ITemplateDataProvider _templateDataProvider;
public TestPlanSetupProvider(IReleaseDataProvider releaseDataProvider, ITemplateDataProvider templateDataProvider)
{
_releaseDataProvider = releaseDataProvider;
_templateDataProvider = templateDataProvider;
}
public CreateTestplanViewModel GetModel()
{
var releases = _releaseDataProvider.GetReleases();
var templates = _templateDataProvider.GetTemplates();
return new CreateTestplanViewModel(releases, templates);
}
}
public class TestPlanController : Controller
{
private readonly IProvideTestPlanSetupModel _testPlanSetupProvider;
public TestPlanController(IProvideTestPlanSetupModel testPlanSetupProvider)
{
_testPlanSetupProvider = testPlanSetupProvider;
}
[HttpGet]
public ActionResult Create()
{
var createTestplanViewModel = _testPlanSetupProvider.GetModel();
return PartialView(createTestplanViewModel);
}
}
如果您不喜欢在控制器之外的任何位置构建视图模型,那么接口可以提供一个中间对象,该对象的属性与您将复制到视图模型的属性相同。但这是愚蠢的,因为这种数据组合只与特定视图相关,而该视图正是视图模型应该表示的
另一方面,通过同一个模型进行读/写操作时,您似乎遇到了相当常见的麻烦。由于这些问题让您非常烦恼,您可能会调查CQR,这可能会让您在直接与数据库进行此类查询时感觉不那么脏,并有助于您绕过我们都非常喜欢的分层迷宫。它看起来很有希望,尽管我还没有在生产应用程序中测试驾驶它的乐趣。EDIT
在我看来,您基本上有以下选项来减少构造函数依赖项计数:
这与我的建议大致相同:
public interface IProvideTestPlanSetupModel
{
CreateTestplanViewModel GetModel();
}
public class TestPlanSetupProvider : IProvideTestPlanSetupModel
{
private readonly IReleaseDataProvider _releaseDataProvider;
private readonly ITemplateDataProvider _templateDataProvider;
public TestPlanSetupProvider(IReleaseDataProvider releaseDataProvider, ITemplateDataProvider templateDataProvider)
{
_releaseDataProvider = releaseDataProvider;
_templateDataProvider = templateDataProvider;
}
public CreateTestplanViewModel GetModel()
{
var releases = _releaseDataProvider.GetReleases();
var templates = _templateDataProvider.GetTemplates();
return new CreateTestplanViewModel(releases, templates);
}
}
public class TestPlanController : Controller
{
private readonly IProvideTestPlanSetupModel _testPlanSetupProvider;
public TestPlanController(IProvideTestPlanSetupModel testPlanSetupProvider)
{
_testPlanSetupProvider = testPlanSetupProvider;
}
[HttpGet]
public ActionResult Create()
{
var createTestplanViewModel = _testPlanSetupProvider.GetModel();
return PartialView(createTestplanViewModel);
}
}
如果您不喜欢在控制器之外的任何位置构建视图模型,那么接口可以提供一个中间对象,该对象的属性与您将复制到视图模型的属性相同。但这是愚蠢的,因为这种数据组合只与特定视图相关,而该视图正是视图模型应该表示的
另一方面,通过同一个模型进行读/写操作时,您似乎遇到了相当常见的麻烦。由于这些问题让您非常烦恼,您可能会调查CQR,这可能会让您在直接与数据库进行此类查询时感觉不那么脏,并有助于您绕过我们都非常喜欢的分层迷宫。它看起来很有希望,尽管我还没有在生产应用程序中测试驱动它的乐趣。一个很好的解耦数据库的通用方法是使用一个工作单元。这是一篇关于的好文章,也是另一篇关于的文章 总之,您可以在所有数据库/服务调用所在的位置创建一个单元,它可以处理数据库逻辑。这将减少多个接口对单个点的依赖性,因此只需向控制器中注入一个类 引用MSDN文章: 根据Martin Fowler的说法,工作单元模式“维护一个列表 受业务事务影响的对象,并协调 写出更改和解决并发问题。”
一个很好的解耦数据库的通用方法是使用一个工作单元。这是一篇关于的好文章,也是另一篇关于的文章 总之,您可以在所有数据库/服务调用所在的位置创建一个单元,它可以处理数据库逻辑。这会将多个接口的依赖性减少到一个点,因此
using System.Diagnostics;
using SimpleInjector;
namespace MyApp.Infrastructure
{
sealed class SimpleQueryProcessor : IQueryProcessor
{
private readonly Container _container;
public SimpleQueryProcessor(Container container)
{
_container = container;
}
[DebuggerStepThrough]
public TResult Execute<TResult>(IDefineQuery<TResult> query)
{
var handlerType = typeof(IHandleQueries<,>)
.MakeGenericType(query.GetType(), typeof(TResult));
dynamic handler = _container.GetInstance(handlerType);
return handler.Handle((dynamic)query);
}
}
}