Как динамически загрузить сборку, созданную из предыдущего интерфейса? - PullRequest
0 голосов
/ 09 октября 2018

У меня есть приложение .net Winform, которое пытается динамически загрузить сборку, но получает исключение ReflectionTypeLoadException

Приложение включает две ссылки на P.DLL и C.DLL (код приведен ниже). Затем динамическизагружает SI.DLL (код для загрузки ниже)

Вот код для ДО моя проблема началась

P.DLL содержит это

public interface iP
{
    string Version { get; }
}

public class P : iP
{
    public P()
    {
        Version = "4.0";
    }

    #region iP Implementation
    public string Version { get; private set; }
    #endregion
}

C.DLL содержит это

//
// C.DLL
//
public interface iC : iP
{
    // no interface changes here
}
public class C : P, iC
{
    public C()
    {
        // this class does stuff but is irrelevant to problem except it is the inheritance chain
    }
}

SI.DLL содержитэто

//
// SI.DLL
//
public interface iSI : iC
{
    // no interface changes here
}

public class SI_Engine : C, iSI
{
    public SI_Engine()
    {
        // this is the object in the SI.DLL assembly that I am trying to load
    }
}

Таким образом, по существу, SI (интерфейс iSI) происходит от C (интерфейс iC), который происходит от P (интерфейс iP)

SI (iSI) : C (iC) : P (iP)

Так что сПриведенный выше код, я могу динамически загрузить SI.DLL, и нет проблем.

Это код в моем приложении, который динамически загружает SI.DLL

Вот код, вызывающий загрузчик:

bool bLoaded = false;
iC retval = LoadPlugin<iC>(fullPathAndFileName, out bLoaded);

Эта функция выполняет загрузку:

    public static T LoadPlugin<T>(string fullPathAndFileName, out bool loaded)
    {
        loaded = false;
        T retval = default(T);

        Assembly assembly = Assembly.LoadFile(fullPathAndFileName);
        if (assembly != null)
        {
            Type pluginType = typeof(T);


            // this is where I am getting the ReflectionTypeLoadException

            Type[] types = assembly.GetTypes();

            // Method 'TimeTrial' in type 'SI.SI_Engine' 
            // from assembly 'SI, Version=4.0.0.0, Culture=neutral, PublicKeyToken=null' 
            // does not have an implementation.
            //

            foreach (Type type in types)
            {
                if (type.IsInterface || type.IsAbstract)
                {
                    continue;
                }
                else
                {
                    if (type.GetInterface(pluginType.FullName) != null)
                    {
                        retval = (T)Activator.CreateInstance(type);
                        loaded = true;

                        break;
                    }
                }
            }
        }

        return retval;
    }

ИЗМЕНЕНИЯ

Я изменил P.DLL, добавив новый интерфейс, производный от старого, и реализовал функцию в классе P:

public interface iP
{
    string Version { get; }
}

public interface iP4 : iP
{
    bool TimeTrial();
}
public class P : iP4
{
    public P()
    {
        Version = "4.0";
    }

    #region iP Implementation
    public string Version { get; private set; }
    #endregion

    #region iP4 Implementation
    public bool TimeTrial()
    {
        return Version == "4.0";
    }
    #endregion
}

Я изменил C.DLLтакже использовать производную от нового интерфейса:

public interface iC : iP4
{
    // no interface changes here
}

С изменениями в P и C:

SI (интерфейс iSI) наследуется от C (интерфейс iC), который наследуется от P (интерфейс iP 4 )

SI (iSI) : C (iC) : P (iP4)

Я внес изменения, перекомпилировал P.DLL и C.DLL и мое приложение.Теперь, когда я запускаю приложение, я пытаюсь загрузить экземпляр SI.DLL, созданный с использованием интерфейса OLD iP , и получаю исключение.

У меня вопрос, как мне динамически загрузитьсборка, построенная из предыдущего интерфейса?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...