Assemblacja i dll-ka w innym miejscu

0

Witam,

W mojej aplikacji muszę odwołać się do kodu z innej dll-ki, lecz wszystko wykonywane jest przez mechanizm refleksji.
Oto fragment kodu:

Assembly assembly = Assembly.LoadFile(sel.DLL);
                Type type = assembly.GetType(sel.NameClass);
                object testInterface = Activator.CreateInstance(type);
                Test test = ((ITest)testInterface).GetTest();
                test.MakeTest();

sel.DLL - to ścieżka do dll-ki.
sel.NameClass - to nazwa klasy
Następnie tworzony jest obiekt i wykonywana w nim pewna logika.

Aplikacja działa prawidłowo jeśli dll-ka szukana jest w tym samym miejscu co plik exe (powyższy program). Aplikacja wtedy zachowuje się prawidłowo, ale jeśli dll-ka znajduje się w innej ścieżce niż nasz program to niestety wywala się błąd, iż nie można było odnaleźć danej metody.

jak temu zaradzić?

Pozdrawiam, Wolacz.

0

uzyj

Assembly.LoadFrom()

?

0

Też niestety nie działa.
Gdy robię tak:

                Assembly assembly = Assembly.LoadFrom(sel.DLL);
                Type type = assembly.GetType(sel.NameClass);
                object testInterface = Activator.CreateInstance(type);
              
                Test test = ((ITest)testInterface).GetTest();
                test.MakeTest();

to program wywala błąd, że nie znalazł pliku, natomiast gdy robię tak:

                Assembly assembly = Assembly.LoadFrom(@"G:\program                            testujacy\KrisUnit\KrisUnitTest\bin\Release\KrisUnitTest.dll");
                Type type = assembly.GetType("KrisUnitTest.MathAlgebTest");
                object testInterface = Activator.CreateInstance(type);
                
                Test test = ((ITest)testInterface).GetTest();
                test.MakeTest();

To jest ok. Nie mam pojęcia o co może chodzić.

0

Już wiem w czym problem.
Niestety rozwiązania problemu nie widzę.

Otóz:
Mam kilka projektów w tym:
KrisUnit - projekt ze zbiorem metod ogólnych - operacje na liczbach, mnożenie, dodawanie itp rzeczy.
KrisUnitTest - projekt testujący ten powyższy.

oraz

TestLib - zawierający w sobie framework testujący.
TestLibView - zawierający w sobie interfejs użytkownika Windows Form i obsługujący na poziomie GUI framework testujący.
TestReflectionFile - projekt obsługujący i ładujący przez refleksję dll-ki. Niezależny od interfejsu, stąd osobny projekt.

Startujący projekt to TestLibView gdzie ukazuje się formatka do wyboru dll-ki.
Wybieram dll-kę KrisUnitTest, gdyż to ona zawiera w sobie metody testowe, które mają być wywołane.
W KrisUnitTest zawarte sa testy metod znajdujących się w Krisunit. Między innymi taka metoda testowa:

        public void AddTest()
        {
            int[] tab = new int[] { 5, 6, 2 };
            MathAlgeb math = new MathAlgeb();
            test.CheckValue("Błędny wynik dodawania.", math.Add(tab) == 13);
        }

Klasa MathAlgeb znajduje się w KrisUnit, gdyż to klasa biznesowa.
Ładując asemblację do KrisUnitTest i wywołując test AddTest, program nie widzi klasy MathAlgeb znajdującej się w KrisUnit (mimo, że znajduje się w tym samym folderze co KrisUnitTest). Wynika to z tego, że uruchomionym programem jest testLibView znajdujący się jeszcze gdzieś indziej.

Jak mogę rozwiązać ten problem?
Przerzucenie dll-ki KrisUnit do folderu gdzie jest dll-ka TestLibView rozwiązuje problem, ale chciałbym jednak aby dll-ka była na swoim miejscu.

0

Ponawiam pytanie, tym razem upraszczając jego formę najbardziej jak się da.

Mam trzy dll-ki.
A i B znajdują się w tym samym katalogu - powiedzmy "Folder".
C - to osobny program znajduje się w zupełnie innym miejscu - powiedzmy - dysk C

program C wywołuje poprzez mechanizm refleksji funkcje z dll-ki B, jednak funkcja ta wymaga inicjacji klasy znajdującej się w dll-ce A. Co za tym idzie - program zachowuje się tak:

  • Aplikacja C woła metodę w dll-ce B.
  • Funkcja jest wywołana prawidłowo, ale program C znajduje się w złej ścieżce i nie możliwa się inicjacja klasy będącej w dll-ce A.

Jak rozwiązać taki problem?

0

Jaki leci exception?
O ile dobrze rouzmiem to nie chodzi o to ze C znajduje sie w zlej, gdyz nie ma to wplywu? Skoro B korzysta z A to musisz zaladowac tez A i musi byc to zrobione wczesniej. Zeby nie pilnowac kolejnosci to mozesz sie zarejstrowac na event AppDomain.AssemblyResolve i w ResolveEventArgs jest przekazywane jaka dllka jest potrzebna.

0

Błąd to:

Test metody: Void AddTest() w klasie KrisUnitTest.MathAlgebTest<<<<<
Rodzaj testu: Test jednostkowy
System.IO.FileNotFoundException: Nie można załadować pliku lub zestawu 'KrisUnit, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' lub jednej z jego zależności. Nie można odnaleźć określonego pliku.
Nazwa pliku: 'KrisUnit, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'
w KrisUnitTest.MathAlgebTest.AddTest()
w TestLib.Test.MakeOneTest(FuncOneTest func) w c:\Users\XXX\KrisUnit\KrisUnit\TestLib\Test.cs:wiersz 69

KrisUnit to dll-ka która jest wymagana przez KrisUnitTest. Po wrzuceniu KrisUnit.dll do miejsca gdzie jest plik Exe wszystko działa.

Tak jak piszesz musiałbym załadować dll-kę KrisUnit i KrisUnitTest, ale nazwy tych dll-ek w założeniu mają być różne. Wtedy bym musiał szukać po referencji jakie dll-ki ładować?
Wydaje mi się to troszkę zbyt karkołomne.

0

Myslalem ze leci inny exception. Jezeli dostajesz FileNotFound to oznacza, ze sciezka ktora podajesz jest bledna. To musi byc pelna sciezka do dllki.

Jezeli A to Twój program, ktory znajduje sie w:

C:\program\A.exe
i chciałbys załadować dllke B, która znajduje sie w:
C:\dllfolder\B.dll

to w A musisz napisac:

var assembly = Assembly.LoadFrom(@"C:\dllfolder\B.dll"); 
0

Nie no to oczywiste.

Mam aplikację biznesową A. Zawiera w sobie dwa projekty:
A1 i A2.

Mam też aplikację testująca. Zawiera ona również dwa projekty:
B1 i B2

Referencje pomiędzy tymi projektami wyglądają tak:
A1 - brak referencji
A2 - Referencje posiada do A1 oraz B1
B1 - Brak referencji
B2 - Referencja do B1

Chciałbym aby program B, a konkretnie projekt B2 odpalił poprzez mechanizm refleksji funkcje w klasie A2.
Robię to poprzez taki oto kod:

                    Assembly assembly = Assembly.LoadFrom(sel.DLL);
                    Type type = assembly.GetType(sel.NameClass);
                    object testInterface = Activator.CreateInstance(type);

                    MethodInfo method = type.GetMethod("MakeFunction");
                    List<ResultTest> result = (List<ResultTest>)method.Invoke(testInterface, null);

problem w tym, że metoda w A2 korzysta z klasy z A1 do której posiada referencję. Po wczytaniu tym kodem powyżej, aplikacja wywala się, że brakuje pliku A1, gdyż wczytuję tylko A2 i wywołuję na nim funkcję.

0

Problem rozwiązałem - okazało się, że w pewnym miejscu ładuję asemblację nie metodą LoadFrom a LoadFile.
Wcześniej ten fragment mi umknął i to on wszystko psuł. Teraz aplikacja działa prawidłowo.

1 użytkowników online, w tym zalogowanych: 0, gości: 1