为什么它需要默认构造函数而不是直接使用我的工厂方法?

And*_*man 1 c# asp.net-core-mvc asp.net-core

使用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();

}
Run Code Online (Sandbox Code Playgroud)

我的控制器有这样的方法:

[HttpGet]
public IActionResult CreateTemplate() => View();

[HttpPost]
public IActionResult CreateTemplate(ITechnicalTask item)
{    
    repo.Templates.Add(item);
    return View("TemplatesList");
}
Run Code Online (Sandbox Code Playgroud)

这是我的表格:

<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>
Run Code Online (Sandbox Code Playgroud)

按下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();
}
Run Code Online (Sandbox Code Playgroud)

当前工厂始终可通过该ModelFactory.Current组件的属性访问.因此,没有可在我的ASP.NET Core MVC项目中访问的类或构造函数.

Dav*_*ine 6

您正在混淆依赖注入模型绑定.有一个很大的不同.请考虑执行以下操作.

注册IModelFactory为服务:

public void ConfigureServices(IServiceCollection services)
{
    services.AddSingleton<IModelFactory>(ModelFactory.Current);

    // Add framework services.
    services.AddMvc();
}
Run Code Online (Sandbox Code Playgroud)

现在在您的控制器中,用于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));
}
Run Code Online (Sandbox Code Playgroud)

你的工厂应该被视为一项服务.模型绑定需要POCO,而不是接口.