我有一个MVC控制器,包含几个抽象(组件)。我想将参数的数量减少到最多4个参数。
为此,我有几个不满足的策略:
有更好的替代方法吗?
这是控制器的代码:
public abstract class BaseVerificatieController : ExtendedController
{
private readonly IReferentieTabellenSysteemSettings referentieTabellenSysteemSettings;
private readonly IProcessManager processManager;
private readonly INavigationManager navigationManager;
private readonly ITransactionFacade transactionFacade;
private readonly IUISupportFacade uiSupportFacade;
private readonly ProcessIndex process;
protected BaseVerificatieController(
IBackHandler backHandler,
IReferentieTabellenSysteemSettings referentieTabellenSysteemSettings,
IProcessManager processManager,
INavigationManager navigationManager,
ITransactionFacade transactionFacade,
IUISupportFacade uiSupportFacade,
ProcessIndex process)
: base(backHandler)
{
this.referentieTabellenSysteemSettings = referentieTabellenSysteemSettings;
this.processManager = processManager;
this.navigationManager = navigationManager;
this.transactionFacade = transactionFacade;
this.uiSupportFacade = uiSupportFacade;
this.process = process;
}
[HttpGet]
public ActionResult Index()
{
var processStep = processManager.StartProcess(process);
return navigationManager.RedirectFromProcessStep(process, processStep);
}
[HttpGet]
public ActionResult Oe()
{
var model = new OeViewModel();
var transactionResult = transactionFacade.VerifyIdentityStart();
model.SetTransactionResult(transactionResult);
return View(model);
}
[HttpPost]
public ActionResult Oe(OeViewModel viewModel)
{
if (viewModel == null)
{
throw new ArgumentNullException("viewModel");
}
var transactionResult = transactionFacade.VerifyIdentityCheckRegisters(viewModel.SKN, null);
if (transactionResult.MoveToStep != Business.Models.ProcessStepIndex.NoStep)
{
return navigationManager.RedirectFromTransactionResult(process, transactionResult);
}
var model = new OeViewModel();
model.SetTransactionResult(transactionResult);
return View(model);
}
[HttpGet]
public ActionResult Oz()
{
var model = new OzViewModel(uiSupportFacade, referentieTabellenSysteemSettings);
var idStaatResult = transactionFacade.IdStaatStart();
model.SetIdStaatResult(idStaatResult);
return View("Oz_SKDB", model);
}
[HttpPost]
public ActionResult Oz(OzViewModel viewModel)
{
return RedirectToAction("Index", "Home");
}
答案 0 :(得分:1)
正如@Maarten在评论中所说的那样,我会摆脱process
的注入并将其注入需要的地方(不要传递它)。
我会进一步将所有视图模型逻辑移动到"查看模型处理程序"并使用中介来执行视图模型处理程序。
然后将在视图模型处理程序中注入transactionFacade
和uiSupportFacade
之类的依赖项。这可以通过以下方式实现:
/// <summary>
/// Specifices that the target class is a view model. This is a marker interface and has no methods.
/// </summary>
public interface IViewModel
{
// Marker interface
}
/// <summary>
/// Handles the <typeparamref name="TViewModel"/>.
/// </summary>
/// <typeparam name="TViewModel">The view model which should be handled.</typeparam>
public interface IHandleViewModel<out TViewModel> where TViewModel : IViewModel
{
/// <summary>
/// Creates a <typeparamref name="TViewModel"/>.
/// </summary>
/// <returns>An instance of the <typeparamref name="TViewModel"/>.</returns>
TViewModel Handle();
}
/// <summary>
/// Handles the <typeparamref name="TViewModel"/> with the argument of <typeparamref name="TInput"/>
/// </summary>
/// <typeparam name="TInput">The argument for the view model</typeparam>
/// <typeparam name="TViewModel">The view model which should be handled.</typeparam>
public interface IHandleViewModel<out TViewModel, in TInput> where TViewModel : IViewModel
{
/// <summary>
/// Creates a <typeparamref name="TViewModel"/>.
/// </summary>
/// <returns>An instance of the <typeparamref name="TViewModel"/>.</returns>
TViewModel Handle(TInput input);
}
/// <summary>
/// Processes and creates view models.
/// </summary>
public interface IProcessViewModels
{
/// <summary>
/// Creates the <typeparamref name="TViewModel"/>.
/// </summary>
/// <returns>The view model</returns>
TViewModel Create<TViewModel>() where TViewModel : IViewModel;
/// <summary>
/// Create the <typeparamref name="TViewModel"/> with an argument of type <typeparamref name="TInput"/>
/// </summary>
/// <typeparam name="TViewModel">The view model which should be constructed</typeparam>
/// <typeparam name="TInput">The type of argument for the view model</typeparam>
/// <param name="input">The argument for the view model</param>
/// <returns>The view model</returns>
TViewModel Create<TViewModel, TInput>(TInput input) where TViewModel : IViewModel;
}
这意味着您可以将一个IProcessViewModels
注入控制器并执行处理程序。例如。通过填充依赖容器(这里是Simple Injector):
/// <summary>
/// Registers the view models in the Simple Injector container
/// </summary>
/// <param name="container">The Simple Injector container</param>
/// <param name="viewModelAssemblies">The assembly location of the view models</param>
public static void RegisterViewModels(this Container container, Assembly[] viewModelAssemblies)
{
if (container == null)
throw new ArgumentNullException("container");
if (viewModelAssemblies == null)
throw new ArgumentNullException("viewModelAssemblies");
container.RegisterSingle<IProcessViewModels, ViewModelProcessor>();
container.RegisterManyForOpenGeneric(typeof(IHandleViewModel<>), viewModelAssemblies);
container.RegisterManyForOpenGeneric(typeof(IHandleViewModel<,>), viewModelAssemblies);
}
以上代码来自我的&#34; Nerve Framework&#34;在这里:https://github.com/janhartmann/nerve-framework/tree/master/NerveFramework.Web.Mvc