プロジェクトのアセンブリへの参照を追加せずに、DLL名とクラス名のみを持っている場合、実行時にオブジェクトをインスタンス化することは可能ですか?クラスはインターフェイスを実装しているため、クラスをインスタンス化したら、インターフェイスにキャストします。
アセンブリ名:
library.dll
タイプ名:
Company.Project.Classname
編集: DLLの絶対パスがないため、Assembly.LoadFile
は機能しません。 DLLは、アプリケーションルートsystem32にあるか、GACにロードされている場合もあります。
はい。 Assembly.LoadFrom
を使用してアセンブリをメモリにロードする必要があります。その後、 Activator.CreateInstance
を使用して、希望するタイプのインスタンスを作成できます。リフレクションを使用して、最初にタイプを調べる必要があります。以下に簡単な例を示します。
Assembly assembly = Assembly.LoadFrom("MyNice.dll");
Type type = Assembly.GetType("MyType");
object instanceOfMyType = Activator.CreateInstance(type);
アセンブリファイル名と型名がある場合は、 Activator.CreateInstance(assemblyName, typeName)
を使用して、.NET型解決にそれを型に解決するように依頼できます。それをtry/catchでラップすると、失敗した場合に、検索されない可能性のある追加のアセンブリを具体的に保存できるディレクトリの検索を実行できます。これは、その時点で前述の方法を使用します。
Activator.CreateInstance 動作するはずです。
IFace object = (IFace)Activator.CreateInstance( "AssemblyName",
"TypeName" )
.Unwrap();
注:型名は完全修飾型でなければなりません。
例:
var aray = (IList)Activator.CreateInstance("mscorlib","System.Collections.ArrayList").Unwrap();
aray.Add(10);
foreach (object obj in aray)
{
Console.WriteLine(obj);
}
この質問といくつかの回答は非常に有用であることがわかりましたが、パスの問題があったため、この回答ではbinディレクトリパスを見つけてライブラリをロードする方法を説明しました。
最初の解決策:
string assemblyName = "library.dll";
string assemblyPath = HttpContext.Current.Server.MapPath("~/bin/" + assemblyName);
Assembly assembly = Assembly.LoadFrom(assemblyPath);
Type T = Assembly.GetType("Company.Project.Classname");
Company.Project.Classname instance = (Company.Project.Classname) Activator.CreateInstance(T);
第二の解決策
string assemblyName = "library.dll";
string assemblyPath = HttpContext.Current.Server.MapPath("~/bin/" + assemblyName);
Assembly assembly = Assembly.LoadFile(assemblyPath);
(Company.Project.Classname) instance = (Company.Project.Classname) Assembly.CreateInstance("Company.Project.Classname");
次のようなインターフェイスに同じ原則を使用できます(クラスを作成しますが、インターフェイスにキャストします)。
(Company.Project.Interfacename) instance = (Company.Project.Interfacename) Assembly.CreateInstance("Company.Project.Classname");
この例はWebアプリケーション用ですが、デスクトップアプリケーションにも同様の方法を使用できます。たとえば、パスのみが異なる方法で解決されます。
Path.GetDirectoryName(Application.ExecutablePath)
Framework v4.5以降では、Activator.CreateInstanceFrom()を使用して、アセンブリ内のクラスを簡単にインスタンス化できます。次の例は、それを使用する方法と、パラメーターを渡して戻り値を取得するメソッドを呼び出す方法を示しています。
// Assuming moduleFileName contains full or valid relative path to Assembly
var moduleInstance = Activator.CreateInstanceFrom(moduleFileName, "MyNamespace.MyClass");
MethodInfo mi = moduleInstance.Unwrap().GetType().GetMethod("MyMethod");
// Assuming the method returns a boolean and accepts a single string parameter
bool rc = Convert.ToBoolean(mi.Invoke(moduleInstance.Unwrap(), new object[] { "MyParamValue" } ));
それは簡単です。
MSDNの例:
public static void Main()
{
// Use the file name to load the Assembly into the current
// application domain.
Assembly a = Assembly.Load("example");
// Get the type to use.
Type myType = a.GetType("Example");
// Get the method to call.
MethodInfo myMethod = myType.GetMethod("MethodA");
// Create an instance.
object obj = Activator.CreateInstance(myType);
// Execute the method.
myMethod.Invoke(obj, null);
}
ここに参照リンクがあります
はい。私が個人的に利用できるようにした例は今のところありません。後で見つけたら投稿します。基本的に、リフレクションを使用してアセンブリをロードし、必要なタイプをプルします。
それまでの間、このリンクから開始してください。
((ISomeInterface)Activator.CreateInstance(Assembly.LoadFile("somePath").GetTypes()[0])).SomeInterfaceMethod();
この種の機能がプロジェクトにどの程度内在しているかに応じて、 MEF のようなものを検討することをお勧めします。
* Assembly.Load **メソッドを使用してアセンブリをロードできます。 Activator.CreateInstanceを使用すると、必要なタイプの新しいインスタンスを作成できます。ロードするクラスの完全な型名を使用する必要があることに注意してください(たとえば、Namespace.SubNamespace.ClassName)。 TypeクラスのメソッドInvokeMemberを使用すると、そのタイプのメソッドを呼び出すことができます。
また、一度ロードされると、AppDomain全体もアンロードされるまでアセンブリをアンロードできないことを考慮してください(これは基本的にメモリリークです)。
Assembly assembly = Assembly.LoadFrom("MyAssembly.dll");
Type type = Assembly.GetType("MyType");
dynamic instanceOfMyType = Activator.CreateInstance(type);
したがって、この方法では、methodinfoを取得してから呼び出すことなく、関数を使用できます。このようにinstanceOfMyType.MethodName();ただし、動的型はコンパイル時ではなく実行時に入力されるため、Intellisenseは使用できません。
はい、そうです。Assemblyクラスで静的なLoadメソッドを使用し、Loadの呼び出しから返されたAssemblyインスタンスでCreateInstanceメソッドを呼び出して呼び出します。
また、必要に応じて、Assemblyクラスの「Load」で始まる他の静的メソッドの1つを呼び出すことができます。
この方法で次のことができます。
using System.Reflection;
Assembly MyDALL = Assembly.Load("DALL"); //DALL name of your Assembly
Type MyLoadClass = MyDALL.GetType("DALL.LoadClass"); // name of your class
object obj = Activator.CreateInstance(MyLoadClass);