2013-12-16 81 views
2

我有一个viewmodel,它使用valueinjector从模型(我也实现了TPT继承)注入值。在此过程中,由于我的自定义属性(属性不是在模型中源)中的一个,我不断收到以下错误:视图模型中的定制属性在TPT继承项目中使用valueinjector

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忽略属性,使之不会尝试设置其他属性之前获得的财产。为此,我试着写定制注射器在员工型号如下:

[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

但是,它不是那么容易在我的情况,我已经在我的基类和派生类继承的一个类。并且为了实现自定义valueinjector也不可能,因为您可以从EmployeeVm viewmodel中看到它。

this.InjectFrom<Employee>(employee); 

如果有人能帮助我实现这个实现或者有其他解决方案,我将不胜感激。

另外,thanx为观众。

回答

3

试试这个:

在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属性自动属性:

public string FullName { get; set; } 

此外,在员工改变倍率的方法:

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。该匹配用于返回源和目标属性是否匹配,并且useSourceProp用于忽略SourceProperty,以便它不映射到目标属性。

在您的方案中,source属性没有全名属性,并且关于匹配,您不必知道该名称不匹配就不会映射该属性。

错误是由于

LastName.ToUpper() 

哪个试图分配值之前的姓氏属性转换为大写。因此,如果您在valueinjector设置值之后在构造函数中设置值,则应该解决问题。

+0

非常感谢。它工作得很好。天才 ... –