2011-01-19 6 views
2

Я хочу, чтобы свойство EmployeeNumber для Employee устанавливалось только базой данных, но мне нужно иметь возможность установить значение для модульного тестирования. Вот почему я сделал хелперный код ниже.Reflection.TargetException problem

Может ли кто-нибудь помочь мне устранить неисправность & исправить это?

Cheers,
Berryl

Helper Код

public static void SetEmployeeNumberFor(Employee employee, EmployeeNumber employeeNumber) 
    { 
     var empNumberProperty = employee.GetType().GetProperty("EmployeeNumber", BindingFlags.Public | BindingFlags.Instance); 

     Check.Invariant(empNumberProperty != null); 
     Check.Invariant(empNumberProperty.PropertyType.Equals(typeof(EmployeeNumber))); 

     empNumberProperty.SetValue(empNumberProperty, employeeNumber, null); 
    } 

Полное исключение

System.Reflection.TargetException : Object does not match target type. 
at System.Reflection.RuntimeMethodInfo.CheckConsistency(Object target) 
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean skipVisibilityChecks) 
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) 
at System.Reflection.RuntimePropertyInfo.SetValue(Object obj, Object value, BindingFlags invokeAttr, Binder binder, Object[] index, CultureInfo culture) 
at System.Reflection.RuntimePropertyInfo.SetValue(Object obj, Object value, Object[] index) 
TestableEmployee.cs(36,0): at Smack.ConstructionAdmin.TestingSupport.ResourceHelper.SetEmployeeNumberFor(Employee employee, EmployeeNumber employeeNumber) 
TestableEmployee.cs(47,0): at Smack.ConstructionAdmin.TestingSupport.ResourceHelperTests.SetEmployeeNumberFor() 

EmployeeNumber Код объекта

public virtual EmployeeNumber EmployeeNumber { 
     get { return _employeeNumber; } 
     protected set { 
      _employeeNumber = value; 
      //base.BusinessId = _employeeNumber; 
     } 
    } 
    private EmployeeNumber _employeeNumber; 

ответ

4

Попробуйте использовать вместо этого:

empNumberProperty.SetValue(employee, employeeNumber, null); 

Вопрос заключается в том, что первый параметр SetValue является объектом, который вы пытаетесь изменить.

При взгляде на MSDN Documentation я также заметил, что этот метод может вызывать MethodAccessException, если «была предпринята незаконная попытка доступа к закрытому или защищенному методу внутри класса», который, похоже, будет применяться в этой ситуации. В разделе примечаний появляется данное уведомление:

Начиная с .NET Framework версии 2.0 с пакетом обновления 1, этот метод может быть использован для доступа непубличных членов, если абонент был предоставлен ReflectionPermission с ReflectionPermissionFlag.RestrictedMemberAccess флагом и если набор грантов непубличных членов ограничивается набором грантов вызывающего абонента или его подмножеством. Чтобы использовать эту функциональность, ваше приложение должно ориентироваться на .NET Framework версии 3.5 или новее.

В качестве альтернативы вы можете попробовать использовать GetSetMethod(bool), но это все равно будет подвержено тем же ограничениям безопасности.

empNumberProperty.GetSetMethod(true).Invoke(employee, new[] { employeeNumber }); 
2
empNumberProperty.SetValue(empNumberProperty, employeeNumber, null); 

Должно быть

empNumberProperty.SetValue(employee, employeeNumber, null);