c# - TPT 继承项目中带有 valueinjector 的 View 模型中的自定义属性

标签 c# inheritance valueinjecter

我有一个 View 模型,它使用 valueinjector 来注入(inject)模型中的值(我还实现了 TPT 继承)。在此过程中,由于我的自定义属性之一(不在模型源中的属性),我不断收到以下错误:

Object reference not set to an instance of an object.

我发现 valueinjector 会时不时地访问该属性。如下面的示例所示,自定义属性是“FullName”。

public class EmployeeVm
{
    public EmployeeVm(Employee employee)
    {
        this.InjectFrom<Employee>(employee);
    }

    public EmployeeVm(int id):this(new Context().Employees.Find(id))
    {
    }

    public EmployeeVm()
    {
    }
    public int EmployeeId { get; set; }
    [Display(Name = "First Name")]
    [Required(ErrorMessage = "Pleae enter First Name"), StringLength(50)]
    public string FirstName { get; set; }
    [Display(Name="Middle Name"), StringLength(50)]
    public string MiddleName { get; set; }
    [Display(Name="Last Name"), StringLength(50)]
    [Required(ErrorMessage = "Please enter Last Name")]
    public string LastName { get; set; }

    public string FullName {
        get
        {
            StringBuilder stringBuilder = new StringBuilder();

            stringBuilder.Append("<b>");
            stringBuilder.Append(LastName.ToUpper());
            stringBuilder.Append("</b>");
            if (!string.IsNullOrEmpty(MiddleName))
            {
                stringBuilder.Append(", ");
                stringBuilder.Append(MiddleName);
            }
            stringBuilder.Append(", ");
            stringBuilder.Append(LastName);

            return stringBuilder.ToString();
        }
    }        
}

我想到的唯一解决方案是让 valueinjector 忽略该属性,以便它在设置其他属性之前不会尝试获取该属性。为此,我尝试在员工模型中编写自定义注入(inject)器,如下所示:

[Table("Person")]
public abstract class Person:ConventionInjection
{
    public Person()
    {
        this.PersonAddresses = new List<PersonAddress>();
        this.PersonEmails = new List<PersonEmail>();
        this.PersonPhones = new List<PersonPhone>();
    }

    [Key]
    public int PersonId { get; set; }
    public string FirstName { get; set; }
    public string MiddleName { get; set; }
    public string LastName { get; set; }



    //public virtual Employee Employee { get; set; }

    protected override bool Match(ConventionInfo c)
    {
      throw new NotImplementedException();
    }



    public List<PersonAddress> PersonAddresses { get; set; }
    public List<PersonEmail> PersonEmails { get; set; }
    public List<PersonPhone> PersonPhones { get; set; }
}

public class Employee:Person
{
    public Employee()
    {
        this.Identifications=new List<Identification>();
        this.BankAccounts=new List<BankAccount>();
    }
    public DateTime? DateOfBirth { get; set; }
    //Other properties are inherited from Person abstract class

    public virtual ICollection<Identification> Identifications { get; set; }
    public virtual ICollection<BankAccount> BankAccounts { get; set; }

    protected override bool Match(ConventionInfo c)
    {
        if (c.TargetProp.Name == "FullName")
        {
            return false;
        }



        var isMatch = (c.SourceProp.Name == "PersonId" && c.TargetProp.Name == "EmployeeId") ||
                      (c.SourceProp.Name == c.TargetProp.Name && c.SourceProp.Type == c.TargetProp.Type);

        return isMatch;

    }
}

尽管如此,我还是不断收到上述相同的错误。

我还找到了另一个解决方案,它说要重写 LoopValueInjection 的 UseSourceProp 方法。

http://valueinjecter.codeplex.com/discussions/234706

但是,在我的场景中这并不容易,因为我已经在基类和派生类中继承了一个类。并且实现自定义值注入(inject)器也是不可能的,正如您从 EmployeeVm View 模型中看到的那样。

this.InjectFrom<Employee>(employee);

如果有人可以帮助我完成此实现或是否有任何其他解决方案,我将不胜感激。

另外,感谢观众。

最佳答案

试试这个:

在EmployeeVm的构造函数中:

public EmployeeVm(Employee employee)
{
    this.InjectFrom<Employee>(employee);

    stringBuilder = new StringBuilder();
    stringBuilder.Append("<b>");
    stringBuilder.Append(LastName.ToUpper());
     stringBuilder.Append("</b>");
     if (!string.IsNullOrEmpty(MiddleName))
     {
           stringBuilder.Append(", ");
           stringBuilder.Append(MiddleName);
     }
      stringBuilder.Append(", ");
     stringBuilder.Append(FirstName);
     this.FullName = stringBuilder.ToString();
}

将 FullName 属性转换为 auto 属性:

public string FullName { get; set; }

此外,将 Employee 中的重写方法更改为:

protected override bool Match(ConventionInfo c)
{
    var isMatch = (c.SourceProp.Name == "PersonId" && c.TargetProp.Name == "EmployeeId") ||(c.SourceProp.Name == c.TargetProp.Name && c.SourceProp.Type == c.TargetProp.Type);

      return isMatch;

}

您不需要重写 LoopValueInjector 的 match 属性或 useSourceProp。 match 用于返回源属性和目标属性是否匹配,useSourceProp 用于忽略 SourceProperty,以便它不会映射到目标属性。

在您的场景中,源属性没有“全名”属性,并且关于匹配,您不必告知,如果名称不匹配,则不会映射该属性。

错误的原因是

LastName.ToUpper()

在分配值之前尝试将 LastName 属性转换为大写。所以,如果在valueinjector设置值之后再在构造函数中设置值,问题应该就可以解决。

关于c# - TPT 继承项目中带有 valueinjector 的 View 模型中的自定义属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20613883/

相关文章:

c# - 我应该在继承链中包含所有接口(interface)吗?

c# - 值注入(inject)器和数据表

c# - 记录函数调用层次结构

c# - 使用 C# 从 sharepoint 站点下载 excel 文件到本地系统

c# - 使用正则表达式获取每个反斜杠之间的字符串

c# - 接口(interface)中的等于方法

Java:从静态方法中获取继承类的类

c# - 如何创建自定义值注入(inject)以将我的实体映射到我的 View 模型?包括尝试

c# Entity Framework 创建审计历史