Есть ли способ получить сборку, содержащую класс с именем TestClass
?
Я просто знаю имя класса, поэтому я не могу создать экземпляр этого. И
Type objectType = assembly.GetType("TestClass");
не работал у меня.
Есть ли способ получить сборку, содержащую класс с именем TestClass
?
Я просто знаю имя класса, поэтому я не могу создать экземпляр этого. И
Type objectType = assembly.GetType("TestClass");
не работал у меня.
Из Type objectType
в вопросе я предполагаю, что вы действительно после типа по имени (а не сборки); поэтому, предполагая, что сборка загружена и имя типа уникально, LINQ может помочь:
Type objectType = (from asm in AppDomain.CurrentDomain.GetAssemblies()
from type in asm.GetTypes()
where type.IsClass && type.Name == "TestClass"
select type).Single();
object obj = Activator.CreateInstance(objectType);
Однако лучше работать с именем с именем сборки вместо имени типа.
Assembly asm = typeof(TestClass).Assembly;
предоставит вам сборку, если на ней ссылаются. В противном случае вам нужно будет использовать полное имя:
Assembly asm = null;
Type type = Type.GetType("TestNamespace.TestClass, ConsoleApplication1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null");
if (type != null)
{
asm = type.Assembly;
}
На самом деле, знание большинства классов достаточно для большинства сценариев. MSDN говорит: если тип находится в текущей исполняемой сборке или в Mscorlib.dll, достаточно указать имя типа, соответствующее его пространству имен.
Type neededType = Type.GetType("TestClass"); //or typeof(TestClass)
Assembly a = neededType.Assembly;
Если вы не знаете сборки, содержащие тип (хотя я не могу представить, почему) -
Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
Asssembly result = assemblies.FirstOrDefault(a=>a.GetType("TestClass",false)!=null);
Единственное ограничение - сборка, содержащая TestClass, должна была быть уже загружена в момент вызова такого кода.
Надеюсь, это поможет.:)
Ответ Marc действительно хорош, но поскольку он был слишком медленным (я часто использую этот метод), я решил пойти другим путем:
private static Dictionary<string, Type> types;
private static readonly object GeneralLock = new object();
public static Type FindType(string typeName)
{
if (types == null)
{
lock (GeneralLock)
{
if (types == null)
{
types = new Dictionary<string, Type>();
var appAssemblies = AppDomain.CurrentDomain.GetAssemblies();
foreach (var appAssembly in appAssemblies)
{
foreach (var type in appAssembly.GetTypes())
if (!types.ContainsKey(type.Name))
types.Add(type.Name, type);
}
}
}
}
return types[typeName];
}
Вы можете обращаться с именем clash так, как хотите, но в этом примере я решил просто игнорировать последующие.