2015-11-23 20 views
1

我有共享驗證邏輯,很大程度上取決於自定義屬性,所以我需要檢查每種類型。一般鑄造對象它是'真正'類型

實例(要檢查的)被取出用於每個驗證訂戶:

var instance = this.ValidationProvider.GetInstanceForSubscriber(validationSubscriber); 

validationSubscriber是使用這些值的枚舉:

人, 檢查

此時,GetInstanceForSubscriber返回類型對象的實例:

public object GetInstanceForSubscriber(ValidationSubscribers validationSubscriber) 
{ 
    switch (validationSubscriber) 
    { 
     case ValidationSubscribers.Person: 
      return new Person(); 
     case ValidationSubscribers.Checks: 
      return new Checks(); 
     default: 
      return null; 
    } 
} 

調用此方法後,我檢查類型:

var instanceType = instance.GetType(); 

然後,我讀了(自定義)屬性:

var attributes = propertyInfo.GetCustomAttributes(true); 

我再返回IEnumerable<PropertyAttribute>列表包含只有我的自定義屬性,將驗證範圍限制爲僅需要的(這是FYI,因爲與此問題不太相關)。

問題

由於instance是類型的對象,它不包含任何我的自定義屬性(邏輯),所以我需要將其轉換爲正確的類類型。

達到此目的的最佳方法是什麼?

+0

您是否具有Enum值和類名稱的完全匹配名稱? –

+0

你爲什麼bell it它不包含你的屬性? – CSharpie

+0

@ShantanuGupta:不,我不贊成,因爲這可能會變得很難維持(而且非常不值得信任)。 – Spikee

回答

3

我建議通過引入界面來修改您的設計。

public interface ICustomAttribute 
{ 
    IEnumerable<PropertyAttribute> GetCustomAttributes(true); 
} 

class Person:ICustomAttribute 
{ 
    IEnumerable<PropertyAttribute> GetCustomAttributes(true) 
    { 
     //Validation logic here for Person entity. 
     //Encapsulate your entity level logic here. 
      return propertyInfo.GetCustomAttributes(true); 
    } 
} 

class Check:ICustomAttribute 
{ 
    IEnumerable<PropertyAttribute> GetCustomAttributes(true) 
    { 
     //Validation logic here for CHECK entity 
     //Encapsulate your entity level logic here. 
      return propertyInfo.GetCustomAttributes(true); 
    } 
} 

public ICustomAttribute GetInstanceForSubscriber(ValidationSubscribers validationSubscriber) 
{ 
    //Use dependency injection to eliminate this if possible 
    switch (validationSubscriber) 
    { 
     case ValidationSubscribers.Person: 
      return new Person(); 
     case ValidationSubscribers.Checks: 
      return new Checks(); 
     default: 
      return null; 
    } 
} 

現在,當你從這個方法接收到一個對象時,你將總是有正確的對象。

var instanceType = instance.GetCustomAttributes(true); //will give you all attributes 

您可以通過利用泛型來進一步增強此邏輯。請參閱this。然而這取決於你如何設計你的實體,因此你可以想出更好的解決方案。

1

一種方法是使重載每種類型要驗證:

void ValidateWithAttributes(Person p, Attribute[] attr) { 
    ... 
} 
void ValidateWithAttributes(Checks c, Attribute[] attr) { 
    ... 
} 
// Add an overload to catch unexpected types 
void ValidateWithAttributes(Object obj, Attribute[] attr) { 
    throw new InvalidOperationException(
     $"Found an object of unexpected type {obj?.GetType()}" 
    ); 
} 

現在你可以投你的對象dynamic,並讓運行時進行調度:

object instance; 
ValidateWithAttributes((dynamic)instance, attributes);