2012-09-23 44 views
1

我有一个注册类型的字典。测试对象实现了字典接口

Dictionary<Type, Type> knownTypes = new Dictionary<Type, Type>() { 
    { typeof(IAccountsPlugin), typeof(DbTypeA) }, 
    { typeof(IShortcodePlugin), typeof(DbTypeB) } 
}; 

我需要测试,如果一个对象实现特定接口作为密钥,并且如果是这样的实例对应的值。

public Plugin FindDbPlugin(object pluginOnDisk) 
{ 
    Type found; 
    Type current = type.GetType(); 

    // the below doesn't work - need a routine that matches against a graph of implemented interfaces 
    knownTypes.TryGetValue(current, out found);/
    if (found != null) 
    { 
     return (Plugin)Activator.CreateInstance(found); 
    } 
} 

将要创建(在这种情况下DbTypeA,DbTypeB等)所有类型将只从Plugin类型派生。

传入的对象可能会继承自我们尝试匹配的其中一种类型(即IAccountsPlugin)几代继承。这就是为什么我不能做pluginOnDisk.GetType()

有没有一种方法来测试一个对象是否实现了一个类型,然后用字典查找来创建该类型的新实例,而不是在长循环中强制并测试typeof?

回答

2

更改此方法是通用的,并指定对象的类型,你正在寻找:

public Plugin FindDbPlugin<TKey>(TKey pluginOnDisk) 
{ 
    Type found; 
    if (knownTypes.TryGetValue(typeof(TKey), out found) && found != null) 
    { 
     Plugin value = Activator.CreateInstance(found) as Plugin; 
     if (value == null) 
     { 
      throw new InvalidOperationException("Type is not a Plugin."); 
     } 

     return value; 
    } 

    return null; 
} 

!例如:

IAccountsPlugin plugin = ... 
Plugin locatedPlugin = FindDbPlugin(plugin); 
+0

也IF((发现的是插件)){抛出新的InvalidOperationException(“不实现插件”); } – dumdum

+0

@dumdum好点。我会编辑。 – Dan

+0

当TKey不在字典 – Laoujin

1
public Plugin FindDbPlugin(object pluginOnDisk) {   
    Type found = pluginOnDisk.GetType().GetInterfaces().FirstOrDefault(t => knownTypes.ContainsKey(t)); 
    if (found != null) { 
     return (Plugin) Activator.CreateInstance(knownTypes[found]); 
    } 
    throw new InvalidOperationException("Type is not a Plugin."); 
}