使用 Visual Studio 2017 我有一个 ASP.NET Core MVC应用程序。我注册了工厂的必要方法,因为在模型中,我的每个类的每个实例都只能通过工厂创建:
public void ConfigureServices(IServiceCollection services)
{
services.AddTransient<ITechnicalTask>(_ =>
// It returns ITechnicalTask instance
ModelFactory.Current.CreateTechnicalTaskTemplate(
"Template Name"));
// Add framework services.
services.AddMvc();
}
我的控制器有这样的方法:
[HttpGet]
public IActionResult CreateTemplate() => View();
[HttpPost]
public IActionResult CreateTemplate(ITechnicalTask item)
{
repo.Templates.Add(item);
return View("TemplatesList");
}
这是我的表格:
<form asp-action="CreateTemplate" method="post">
<div class="form-group">
<label asp-for="TemplateName">Template name:</label>
<input class="form-control" asp-for="TemplateName" />
</div>
<div class="text-center">
<button class="btn btn-primary" type="submit">
Accept
</button>
</div>
</form>
按Accept
按钮时出现异常:
处理请求时发生未处理的异常。
InvalidOperationException:无法创建类型的实例 'PikProject.RobotIRA.ITechnicalTask'。模型绑定复杂类型必须 不是抽象或值类型,必须具有无参数 构造
Microsoft.AspNetCore.Mvc.ModelBinding.Binders.ComplexTypeModelBinder.CreateModel(ModelBindingContext 的BindingContext)
为什么它需要默认构造函数?为什么使用我的工厂方法是不够的?
UPD
我的商业模式位于其他项目中。它的所有类都是internal
。只有接口和耦合类为public
。它还定义工厂接口,用于创建接口的必要实例:
public interface IModelFactory {
IEmployee CreateEmployee(string name,
string middleName, string surname,
string post);
IAddress CreateAddress(string country, string region,
string town, string street, string hoseNumber = "",
string notes = "");
IApproval CreateApproval(IEmployee employee,
DateTime? datetime = null);
IApprovalCollection CreateApprovalCollection();
IRequirementsCollection CreateRequirementsCollection();
IRequirement CreateRequirement(RequirementTypes type);
ITechnicalTask CreateTechnicalTaskTemplate(string name);
ITechnicalTask CreateTechnicalTaskDocument(
string templateName);
ITechnicalTaskCollection CreateTechnicalTaskCollection();
IRepository CreateRepository();
}
始终可以通过该程序集的ModelFactory.Current
属性访问当前工厂。因此,没有可在我的ASP.NET Core MVC
项目中访问的类或构造函数。
答案 0 :(得分:6)
您感到困惑dependency injection和model binding。有一个很大的不同。请考虑采取以下措施。
将IModelFactory
注册为服务:
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<IModelFactory>(ModelFactory.Current);
// Add framework services.
services.AddMvc();
}
现在在您的控制器中,使用FromServices
来获取实例,并使用FromForm
从帖子中获取创建模型所需的值:
[HttpPost]
public IActionResult CreateTemplate([FromForm] string name,
[FromServices] IModelFactory factory)
{
var item = factory.CreateTechnicalTaskTemplate(name);
repo.Templates.Add(item);
return View(nameof(TemplatesList));
}
您的工厂应该被视为一项服务。模型绑定需要POCO,而不是接口。