为什么它需要默认构造函数而不是直接使用我的工厂方法? [英] Why It requires the default constructor instead of using my factory method directly?

查看:103
本文介绍了为什么它需要默认构造函数而不是直接使用我的工厂方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用 Visual Studio 2017 ,我有一个 ASP.NET Core MVC应用程序.我注册了工厂的必要方法,因为在模型中,每个类的每个实例只能通过工厂创建:

Using Visual Studio 2017 I have an ASP.NET Core MVC application. I registered the necessary method of my factory, because in the model each instance of each my class can be created only through the factory:

public void ConfigureServices(IServiceCollection services)
{
    services.AddTransient<ITechnicalTask>(_ =>
        // It returns ITechnicalTask instance
        ModelFactory.Current.CreateTechnicalTaskTemplate(
            "Template Name"));

    // Add framework services.
    services.AddMvc();

}

我的控制器具有以下方法:

My controller has such methods:

[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按钮时出现异常:

处理请求时发生未处理的异常.

An unhandled exception occurred while processing the request.

InvalidOperationException:无法创建类型的实例 'PikProject.RobotIRA.ITechnicalTask​​'.模型绑定的复杂类型必须 不能是抽象或值类型,并且必须具有无参数 构造函数.

InvalidOperationException: Could not create an instance of type 'PikProject.RobotIRA.ITechnicalTask'. Model bound complex types must not be abstract or value types and must have a parameterless constructor.

Microsoft.AspNetCore.Mvc.ModelBinding.Binders.ComplexTypeModelBinder.CreateModel(ModelBindingContext bindingContext)

Microsoft.AspNetCore.Mvc.ModelBinding.Binders.ComplexTypeModelBinder.CreateModel(ModelBindingContext bindingContext)

为什么需要默认构造函数?为什么使用我的工厂方法还不够?

Why It requires the default constructor? Why it is not enough to use my factory method?

UPD

我的业务模型位于其他项目中.它的所有类都是internal.仅接口和一对类为public.它还定义了工厂接口,用于创建接口的必要实例:

My business-model is located in other project. All its classes are internal. Only interfaces and couple classes are public. Also it defines the factory interface for creating of necessary instances of the interfaces:

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项目中没有可访问的类或构造函数.

The current factory is always accessible through the ModelFactory.Current property of that assembly. So, no classes or constructors which are accessible in my ASP.NET Core MVC project.

推荐答案

您正在混淆依赖注入

You are confusing dependency injection and model binding. There is a big difference. Consider doing the following instead.

IModelFactory注册为服务:

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

    // Add framework services.
    services.AddMvc();
}

现在在您的控制器中,使用FromServices获取实例,然后从帖子中获取使用FromForm创建模型所需的值:

Now in your controller, use FromServices to get the instance and from the post take the value needed to create your model using 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,而不是接口.

You're factory should be treated as a service. Model binding expects a POCO, not an interface.

这篇关于为什么它需要默认构造函数而不是直接使用我的工厂方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆