web-dev-qa-db-ja.com

C#での実行時のDLLのロード

C#アプリケーション内で実行時に.dllをインポートして使用する方法を見つけようとしています。 Assembly.LoadFile()を使用して、プログラムにdllをロードさせることができました(ToString()でクラスの名前を取得できるため、この部分は間違いなく機能しています)が、「出力」を使用することはできませんコンソールアプリケーション内からのメソッド。 .dllをコンパイルしてから、コンソールのプロジェクトに移動しています。 CreateInstanceの間に追加のステップがあり、メソッドを使用できるようになっていますか?

これは私のDLLのクラスです:

namespace DLL
{
    using System;

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

そして、ここにDLLをロードしたいアプリケーションがあります

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();
        }
    }
}
72
danbroooks

メンバーは、C#から直接呼び出されるように、コンパイル時に解決可能でなければなりません。それ以外の場合は、反射オブジェクトまたは動的オブジェクトを使用する必要があります。

反射

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();
        }
    }
}

動的(.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();
        }
    }
}
101
Dark Falcon

現在、アセンブリで定義されているすべてのタイプのインスタンスを作成しています。メソッドを呼び出すには、Class1の単一のインスタンスを作成するだけです。

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();
    }
}
33
Reed Copsey

Outputメソッドを公開する型のインスタンスを作成する必要があります。

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();
     }
12
Alberto

ループ内のクラスの動的参照を渡したい3つのループがあります

プライベートオブジェクトextractSeatLayout(dynamic 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()は、Outputメソッドを持たないオブジェクトを返します。

動的プログラミング言語から来ているように見えますか? C#はそうではありません。あなたがやろうとしていることは難しいでしょう。

特定の場所から特定のdllをロードしているため、コンソールアプリケーションへの参照として追加したいだけかもしれません。

Assembly.Load経由で絶対にアセンブリをロードする場合は、リフレクション経由でcのメンバーを呼び出す必要があります。

type.GetMethod("Output").Invoke(c, null);のようなものがそれを行うべきです。

0
Fredrik