wake-up-neo.net

DLLs zur Laufzeit in C # laden

Ich versuche herauszufinden, wie Sie eine .dll zur Laufzeit in einer C # -Anwendung importieren und verwenden können. Mit Assembly.LoadFile () habe ich es geschafft, dass mein Programm die DLL lädt (dieser Teil funktioniert definitiv, da ich mit ToString () den Namen der Klasse abrufen kann), jedoch kann ich die 'Ausgabe' nicht verwenden. Methode aus meiner Konsolenanwendung. Ich kompiliere die .dll und verschiebe sie dann in das Projekt meiner Konsole. Gibt es einen zusätzlichen Schritt zwischen CreateInstance und anschließendem Verwenden der Methoden?

Dies ist die Klasse in meiner DLL:

namespace DLL
{
    using System;

    public class Class1
    {
        public void Output(string s)
        {
            Console.WriteLine(s);
        }
    }
}

und hier ist die Anwendung, die ich die DLL laden möchte

namespace ConsoleApplication1
{
    using System;
    using System.Reflection;

    class Program
    {
        static void Main(string[] args)
        {
            var DLL = Assembly.LoadFile(@"C:\visual studio 2012\Projects\ConsoleApplication1\ConsoleApplication1\DLL.dll");

            foreach(Type type in DLL.GetExportedTypes())
            {
                var c = Activator.CreateInstance(type);
                c.Output(@"Hello");
            }

            Console.ReadLine();
        }
    }
}
66
danbroooks

Mitglieder müssen zur Kompilierzeit auflösbar sein, um direkt von C # aufgerufen zu werden. Ansonsten müssen Sie Reflexions- oder dynamische Objekte verwenden.

Reflexion

namespace ConsoleApplication1
{
    using System;
    using System.Reflection;

    class Program
    {
        static void Main(string[] args)
        {
            var DLL = Assembly.LoadFile(@"C:\visual studio 2012\Projects\ConsoleApplication1\ConsoleApplication1\DLL.dll");

            foreach(Type type in DLL.GetExportedTypes())
            {
                var c = Activator.CreateInstance(type);
                type.InvokeMember("Output", BindingFlags.InvokeMethod, null, c, new object[] {@"Hello"});
            }

            Console.ReadLine();
        }
    }
}

Dynamisch (.NET 4.0)

namespace ConsoleApplication1
{
    using System;
    using System.Reflection;

    class Program
    {
        static void Main(string[] args)
        {
            var DLL = Assembly.LoadFile(@"C:\visual studio 2012\Projects\ConsoleApplication1\ConsoleApplication1\DLL.dll");

            foreach(Type type in DLL.GetExportedTypes())
            {
                dynamic c = Activator.CreateInstance(type);
                c.Output(@"Hello");
            }

            Console.ReadLine();
        }
    }
}
95
Dark Falcon

Im Moment erstellen Sie eine Instanz von jedem Typ, der in der Assembly definiert ist. Sie müssen nur eine einzige Instanz von Class1 erstellen, um die Methode aufzurufen:

class Program
{
    static void Main(string[] args)
    {
        var DLL = Assembly.LoadFile(@"C:\visual studio 2012\Projects\ConsoleApplication1\ConsoleApplication1\DLL.dll");

        var theType = DLL.GetType("DLL.Class1");
        var c = Activator.CreateInstance(theType);
        var method = theType.GetMethod("Output");
        method.Invoke(c, new object[]{@"Hello"});

        Console.ReadLine();
    }
}
31
Reed Copsey

Sie müssen eine Instanz des Typs erstellen, die die Output-Methode verfügbar macht:

static void Main(string[] args)
    {
        var DLL = Assembly.LoadFile(@"C:\visual studio 2012\Projects\ConsoleApplication1\ConsoleApplication1\DLL.dll");

        var class1Type = DLL.GetType("DLL.Class1");

        //Now you can use reflection or dynamic to call the method. I will show you the dynamic way

        dynamic c = Activator.CreateInstance(class1Type);
        c.Output(@"Hello");

        Console.ReadLine();
     }
11
Alberto

Ich habe 3 Schleifen, an denen ich die dynamische Referenz der Klasse in Schleifen übergeben möchte 

privates Objekt extractSeatLayout (dynamisches colA) {

        //Type type1 = Assembly.GetType("Bigtree.VistaRemote.objArea");
        //dynamic objArea = Activator.CreateInstance(type1, null);

        //Type type2 = Assembly.GetType("Bigtree.VistaRemote.objRow");
        //dynamic objR = Activator.CreateInstance(type2, null);

        //Type type3 = Assembly.GetType("Bigtree.VistaRemote.objSeat");
        //dynamic objS = Activator.CreateInstance(type3, null);



        Dictionary<string, object> collectionArea = new Dictionary<string, object>();


        //collectionArea.Add("Count", colA.Count);
        //collectionArea.Add("intMaxSeatId", colA.intMaxSeatId());
        //collectionArea.Add("intMinSeatId", colA.intMinSeatId());

        try
        {
            collectionArea.Add("Count", colA.GetType().GetProperty("Count").GetValue(colA, null));
            collectionArea.Add("intMaxSeatId", colA.GetType().GetMethod("intMaxSeatId").Invoke(colA, null));
            collectionArea.Add("intMinSeatId", colA.GetType().GetMethod("intMinSeatId").Invoke(colA, null));
        }
        catch (Exception ex)
        {
            throw ex;

        }
        List<Dictionary<string, object>> arrayArea = new List<Dictionary<string, object>>();

        foreach (dynamic objA in colA)
        {
            Dictionary<string, object> area = new Dictionary<string, object>();

            ////area.Add("AreaDesc", objA.strAreaDesc);
            //    //area.Add("AreaCode", objA.strAreaCode);
            //    //area.Add("AreaNum", objA.strAreaNum);
            //    //area.Add("HasCurrentOrder", objA.blnHasCurrentOrder());
            area.Add("AreaDesc", objA.GetType().GetProperty("strAreaDesc").GetValue(objA, null));
            area.Add("AreaCode", objA.GetType().GetProperty("strAreaCode").GetValue(objA, null));
            area.Add("AreaNum", objA.GetType().GetProperty("strAreaNum").GetValue(objA, null));
            area.Add("HasCurrentOrder", objA.GetType().GetMethod("blnHasCurrentOrder").Invoke(objA, null));


            List<Dictionary<string, object>> arrayRow = new List<Dictionary<string, object>>();
            foreach (dynamic objR in objA)
            {
                Dictionary<string, object> row = new Dictionary<string, object>();
                //row.Add("GridRowId", objR.intGridRowID);
                //row.Add("PhyRowId", objR.strRowPhyID);
                row.Add("GridRowId", type.GetProperty("intGridRowID").GetValue(objR, null));
                row.Add("PhyRowId", type.GetProperty("strRowPhyID").GetValue(objR, null));
                List<Dictionary<string, object>> arraySeat = new List<Dictionary<string, object>>();
                var rowCount = 0;
                foreach (dynamic objS in objR)
                {
                    Dictionary<string, object> seat = new Dictionary<string, object>();
                    //seat.Add("GridSeatNum", objS.intGridSeatNum);
                    //seat.Add("SeatStatus", objS.strSeatStatus);
                    //seat.Add("Xpos", objS.dblSeatXPos);
                    //seat.Add("StrSeatNumber", objS.strSeatNumber);
                    //seat.Add("seatNumber", ++rowCount);
                    //seat.Add("type", objS.strGroupSeatType);
                    seat.Add("GridSeatNum", type.GetProperty("intGridSeatNum").GetValue(objS, null));
                    seat.Add("SeatStatus", type.GetProperty("strSeatStatus").GetValue(objS, null));
                    seat.Add("Xpos", type.GetProperty("dblSeatXPos").GetValue(objS, null));
                    seat.Add("StrSeatNumber", type.GetProperty("strSeatNumber").GetValue(objS, null));
                    seat.Add("seatNumber", ++rowCount);
                    seat.Add("type", type.GetProperty("strGroupSeatType").GetValue(objS, null));
                    arraySeat.Add(seat);
                }
                row.Add("objSeat", arraySeat);
                arrayRow.Add(row);
            }
            area.Add("objRow", arrayRow);
            arrayArea.Add(area);
        }

        collectionArea.Add("objArea", arrayArea);

        return collectionArea;


    }
0
Manoj Mishra

Activator.CreateInstance() gibt ein Objekt zurück, das keine Ausgabemethode hat.

Wie es aussieht, kommen Sie aus dynamischen Programmiersprachen? C # ist definitiv nicht das, und was Sie zu tun versuchen, wird schwierig sein.

Da Sie eine bestimmte DLL von einem bestimmten Speicherort laden, möchten Sie sie möglicherweise nur als Referenz zu Ihrer Konsolenanwendung hinzufügen.

Wenn Sie die Assembly unbedingt über Assembly.Load laden möchten, müssen Sie über Reflection alle Mitglieder über c aufrufen.

Etwas wie type.GetMethod("Output").Invoke(c, null); sollte es tun.

0
Fredrik