Динамическая подгрузка DLL

318
27 сентября 2017, 07:55

Допустим, у меня есть метод:

private void UnZip(string FileName, string Path)
{
    using (ZipFile zip = new ZipFile(FileName))
    {
        zip.ExtractAll(Path, ExtractExistingFileAction.DoNotOverwrite);
        zip.Dispose();
    }
}

Он содержится в using Ionic.Zip. Как мне, не указывая его в Reference, использовать классы и методы, подгружая динамически.

Assembly a = Assembly.LoadFile(@"C:\DotNetZip.dll");
Type classType = a.GetType("Ionic.Zip.ZipFile");
object CreateInst = Activator.CreateInstance(classType);
MethodInfo method = classType.GetMethod("ExtractAll");
Answer 1

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

Просто подпишитесь на него в точке входа в приложение:

static void Main(string[] args)
{
    AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
    ...

И в обработчике загрузите нужную сборку:

private static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
    if (args.Name == "DotNetZip, Version=1.10.1.0, Culture=neutral, PublicKeyToken=6583c7c814667745")
        return Assembly.LoadFile(@"C:\DotNetZip.dll");
    return null;
}

Обратите внимание, это необычное событие - оно имеет возвращаемое значение. Мы должны загрузить нужную сборку и вернуть её. При возврате null будет инициировано исключение.

Всё. Метод будет работать в его первозданном виде:

private void UnZip(string FileName, string Path)
{
    using (ZipFile zip = new ZipFile(FileName))
    {
        zip.ExtractAll(Path, ExtractExistingFileAction.DoNotOverwrite);
        //zip.Dispose(); это не нужно тут
    }
}

Если вы всё же намерены действовать через рефлексию, у меня работает такой вариант:

private static void UnZip(string FileName, string Path)
{
    Assembly a = Assembly.LoadFile(@"C:\DotNetZip.dll");
    Type classType = a.GetType("Ionic.Zip.ZipFile");
    object inst = Activator.CreateInstance(classType, new object[] { FileName });
    Type fileActionType = a.GetType("Ionic.Zip.ExtractExistingFileAction");
    object doNotOverwrite = Enum.ToObject(fileActionType, 2);
    MethodInfo method = classType.GetMethod("ExtractAll", new[] { typeof(string), fileActionType });
    method.Invoke(inst, new object[] { Path, doNotOverwrite });
    MethodInfo disposeMethod = classType.GetMethod("Dispose");
    disposeMethod.Invoke(inst, new object[0]);
}
READ ALSO
Как правильно создать gulp файл под сборку с babel для es6? сборка переводит класс с require который не работает в браузере

Как правильно создать gulp файл под сборку с babel для es6? сборка переводит класс с require который не работает в браузере

ЗдравствуйтеХочу делать сборку с gulp-babel, вроде как оно пересобирает проект под старый стандарт, но классы пересоздает с каким-то "require", и браузер...

335
как узнать какое событие происходит в данный момент когда ГУГЛ переводчик виджет переводит сайт на другой язык

как узнать какое событие происходит в данный момент когда ГУГЛ переводчик виджет переводит сайт на другой язык

Куда нужно посмотреть чтобы увидеть какое событие происходит в момент перевода страницы?

310
es6-class. Объявление метода через new

es6-class. Объявление метода через new

Новый синтаксис классов позволяет объявлять методы через 'new'?

233
hasAttribute -VS- getAttribute

hasAttribute -VS- getAttribute

Тут есть решённая задача - http://plnkrco/edit/FaKoF0M4QQB1OSdtpClb?p=preview

303