2017-09-07 15 views
0

私のプロジェクトで1つのDLLの参照を追加し、そのDLLのメソッド/クラスに正常にアクセスできました。リフレクション:オブジェクトの初期化

コードDLL内:(私はこのコードを変更するためのアクセス権を持っていない)

//Dll: myDllName 
    Namespace myNamespace 
     Public Class MyClass 
       Private Sub New(ByVal parameter1 As Int64) 
        //Set some values 
       End Sub 

       Public Shared Function MyPublicFunction(ByVal Parameter1 As Int64,ByVal Parameter2 As INt64,ByVal Parameter2 As Int64) As MyClass 
       Dim retMyClass As New MyClass(Parameter1) 
       //Set Other Values 

       Return retMyClass 
      End Function 

      Public Function Post() As Boolean 
      //Do some operation 
      End Function 
     End Class 
    End Namespace 

私はDLLの上に呼ばれている私のコード:

Dim myObj As myDllName.myNamespace.MyClass 
myObj = myDllName.myNamespace.MyClass.MyPublicFunction(Parameter1, Parameter2, Parameter3) 

myObj.Prop1 = MyVal1 
myObj.Prop2 = MyVal2 
myObj.Prop3 = MyVal1 
myObj.Post() 

今私の要件は、私が達成したいですDLLの参照をプロジェクトに追加することなく、上記のタスクを実行できます。 私はこれを反射で達成しようとしました。

Dim assembly As Reflection.Assembly = Reflection.Assembly.LoadFile("..\\myDllName.dll") 
Dim t As Type = assembly.GetType("myDllName.myNamespace.MyClass") 
Dim woFacadeinst As Object = Activator.CreateInstance(t) 

しかし、オブジェクトの初期化時に、それは私にそのコンストラクタタイプの

myDllName.myNamespace.MyClass見つからない

エラーがスローされます。

私のDLL参照クラスのプライベートNEWメソッドのためだと思います。 誰かがこれに助けてもらえますか?次のように代わりActivator.CreateInstance()のパラメータ化コンストラクタ使用GetConstructors()Invoke()については

+0

の可能性のある重複した[タイプは、パラメータなしのコンストラクタを提供する場合どのようにチェックしますか?](https://stackoverflow.com/questions/4681031/how-do-i-check-if-a-type-provides-a -parameterless-コンストラクタ) –

答えて

1

Dim constructor = t.GetConstructors(BindingFlags.NonPublic Or BindingFlags.Instance) 

Dim woFacadeinst As Object = constructor(0).Invoke(New Object() {5}) 

それがこのlinkでグラフをチェックし、より多くの時間がかかるため、あなたがコンパイルしたラムダ式を試すためにパフォーマンスが本当に重要ならば、それは両方より速いです。

+0

彼は 'Activator.CreateInstanceを(使用してはならない理由を説明することができます代わりに –

+0

をこの回答を試してみてください)' –

+0

は私の更新の答え:)リンクと明確化のため –

0

このライン

Dim woFacadeinst As Object = Activator.CreateInstance(t) 

であなたが存在しないパラメータ以下のコンストラクタを呼び出すようにしてみてくださいので、あなたは、この例外に実行されています。

したがって、必要なパラメータをコンストラクタに渡すために、いくつかのパラメータを使用してActivator.CreateInstance()を呼び出す必要があります。 Bindingflags としている権利を民間のコンストラクタを取得するために

Dim woFacadeinst As Object = Activator.CreateInstance(GetType(Class1), 
                 BindingFlags.NonPublic Or BindingFlags.Instance, 
                 Nothing, New Object(){ 5 }, Nothing) 

トリック:

var woFacadeinst = Activator.CreateInstance(typeof(Class1), BindingFlags.NonPublic | BindingFlags.Instance, 
              null, new object[] { 5 }, null); 

とvb.Netなど:

Private Sub New(ByVal parameter1 As Int64) 
    'Set some values 
End Sub 

は、通常、C#で、私は次のコードを使用しましたnew object[]{ 5 }コンストラクタによって要求されたパラメータを設定しています。


ヒント:パフォーマンス上の問題のためにAli Ezzat Odeh' Answerを見てみましょう。

あなたがGetConstructor()メソッドを使用する場合は、次のC#のようにこれを行うことができますがスニペット:C#の例として

var test = typeof(Class1).GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, 
              null, new Type[] { typeof(Int64) }, null) 
          ?.Invoke(new object[] { 64 }); 

を:

クラス:

public class Class1 
{ 
    private Class1(string myString) 
    { 
     MyIntProperty = 42; 
     MyStringProperty = myString; 
    } 

    private Class1(int myInt) 
    { 
     MyIntProperty = myInt; 
     MyStringProperty = "default"; 
    } 

    private Class1(Int64 myInt64) 
    { 
     MyInt64Property = myInt64; 
     MyStringProperty = "default"; 
    } 

    public string MyStringProperty { get; set; } 
    public int MyIntProperty { get; set; } 
    public Int64 MyInt64Property { get; set; } 
} 

テストスニペット

string testString = "Test"; 
int testInt = 123; 

var objArray = new object[1]; 

objArray[0] = testString; 
var testClass1 = Activator.CreateInstance(typeof(Class1), BindingFlags.NonPublic | BindingFlags.Instance, 
              null, objArray, null); 

objArray[0] = testInt; 
var testClass2 = Activator.CreateInstance(typeof(Class1), BindingFlags.NonPublic | BindingFlags.Instance, 
              null, objArray, null); 

var testCtorClass = typeof(Class1).GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, 
                null, new Type[] { typeof(Int64) }, null) 
            ?.Invoke(new object[] { 64 }); 
0

あなたはそれがどのコンストラクタの要件を持っていないので、このAPIは、任意のコンストラクタを使用していないvar myClass = FormatterServices.GetUninitializedObject(typeof(MyClass));を試みることができます。

関連する問題