Как получить абстрактный тип из загруженной сборки C #?

Можно ли получить абстрактный тип из данной сборки во время выполнения?

В настоящее время я загружаю свою сборку с помощью:

Assembly assem = Assembly.LoadFrom("MyAssemblyName.dll");

Но потом я хочу сделать вот что:

Type t = assem.GetType("Enterprise.Shared_Party_PersonType");

Мой класс определяется как:

public abstract class Shared_Party_PersonType

Но тип t возвращает ноль.

Моя конечная цель - перемещаться по абстрактному классу с отражением и получать список свойств этого абстрактного класса, аналогичный тому, что они делают здесь: доступ-к-свойств-абстрактного-класса-с-отражением

Любая помощь будет очень признательна.

Решение. Оказалось, что я загружал неправильную версию DLL, которая не содержала абстрактный тип, который я пытался загрузить. Однако теперь я знаю, что вы можете перемещаться и управлять абстрактными типами с помощью отражения, как и любым другим конкретным типом. Также я узнал о методе Assembly.RefelectionOnlyLoadFrom благодаря @Fuex для загрузки сборки в контексте только для отражения.


person Adolfo Perez    schedule 14.08.2012    source источник
comment
Да, это публично: public abstract class Shared_Party_PersonType   -  person Adolfo Perez    schedule 14.08.2012
comment
@Adolfo Вам просто нужно проверять информацию или вызывать / создавать экземпляры типов?   -  person Omar    schedule 15.08.2012
comment
@Fuex Мне просто нужно рекурсивно проверить свойства абстрактного типа, чтобы извлечь пути привязки, которые соответствуют определенным условиям.   -  person Adolfo Perez    schedule 15.08.2012
comment
Хорошо, я опубликовал свое решение.   -  person Omar    schedule 15.08.2012


Ответы (3)


Возможно, ваш класс определен внутри какого-то другого класса. В этом случае вы должны использовать + (плюс) вместо . (точка). Нравится:

assem.GetType("OutermostNamespace.InnerNamespace.Enterprise+Shared_Party_PersonType")

где Enterprise - это «внешний» класс или структура, внутри которой Shared_Party_PersonType определено.

В противном случае вы можете получить доступ к исходному коду MyAssemblyName.dll? Затем вы можете попытаться увидеть, что там возвращает string n = typeof(Shared_Party_PersonType).FullName, чтобы проверить, действительно ли имя типа соответствует вашему предположению.

person Jeppe Stig Nielsen    schedule 14.08.2012
comment
Спасибо @JeppeStigNielsen. Оказывается, я загружал неправильную версию DLL. Я понял, попробовав то, что вы предложили. - person Adolfo Perez; 15.08.2012

Да, вы можете получить любой тип, даже интерфейс. Просто убедитесь, что вы указали его полное имя, включая пространство имен:

Type t = assem.GetType("SomeNamespace.AnAbstractClassName", true);

Полный пример:

using System;
using System.Reflection;

namespace SomeNs
{
    public abstract class Foo
    {

    }
}

public class Program
{
    static void Main()
    {
        var asm = Assembly.GetExecutingAssembly();
        var type = asm.GetType("SomeNs.Foo", true);
        Console.WriteLine(type);
    }
}
person Darin Dimitrov    schedule 14.08.2012
comment
Я указываю полное имя с пространством имен, но возвращает ноль. Даже когда я проверяю вручную, перечисление Assem.GetTypes () даже не существует, но оно точно находится в DLL. Я вижу это в обозревателе объектов. - person Adolfo Perez; 14.08.2012
comment
Возможно, вы ссылались на более старую версию сборки, не содержащую этого типа. В любом случае это должно сработать. Метод GetType позволяет извлекать абстрактные типы из сборки. Даже если они внутренние. - person Darin Dimitrov; 14.08.2012
comment
Странно, это работает, когда мой абстрактный класс является частью решения, как в вашем примере. Но не работает, когда я загружаю внешнюю сборку с Assembly.LoadFrom. Не знаю почему ... - person Adolfo Perez; 15.08.2012

Мне просто нужно рекурсивно проверить свойства абстрактного типа, чтобы извлечь пути привязки, которые соответствуют определенным условиям.

Поскольку Assembly.LoadFrom() может иметь нежелательные эффекты, лучшее решение, если вам просто нужно проверить информацию о типе, - это использовать Assembly.ReflectionOnlyLoadFrom().

Так что постарайтесь:

Assembly asm = Assembly.ReflectionOnlyLoadFrom("mypath");
Type t = asm.GetType("FullName");
person Omar    schedule 14.08.2012