Reputation: 464
I'm trying to instantiate an object from a dll without referencing it. I can do it using Reflection in VB.NET but can't figure out how to do it in C#.
In VB.NET:
Public Class Form1
Dim bytes() As Byte = System.IO.File.ReadAllBytes("\\path\directory\file.dll")
Dim assmb As System.Reflection.Assembly = System.Reflection.Assembly.Load(bytes)
Dim myDllClass As Object = assmb.CreateInstance("myNamespace.myClass")
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim conStr As String = myDllClass.publicConString
Dim dt As DataTable = myDllClass.MethodReturnsDatatable("select * from Part", conStr)
DataGridView1.DataSource = dt
End Sub
In C#:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
static byte[] bytes = System.IO.File.ReadAllBytes(@"\\path\directory\file.dll");
static System.Reflection.Assembly assmb = System.Reflection.Assembly.Load(bytes);
object myDllClass = assmb.CreateInstance("myNamespace.myClass");
private void Form1_Load(object sender, EventArgs e)
{
string conStr = myDllClass.publicConString;
DataTable dt = myDllClass.MethodReturnsDatatable("select * from Part", conStr);
dataGridView1.DataSource = dt;
}
}
I get these two errors:
Error 1 'object' does not contain a definition for 'publicConString' and no extension method 'publicConString' accepting a first argument of type 'object' could be found (are you missing a using directive or an assembly reference?) C:\Users\Username\Desktop\C#\FormTest\FormTest\Form1.cs 29 34 FormTest
Error 2 'object' does not contain a definition for 'MethodReturnsDatatable' and no extension method 'MethodReturnsDatatable' accepting a first argument of type 'object' could be found (are you missing a using directive or an assembly reference?) C:\Users\Username\Desktop\C#\FormTest\FormTest\Form1.cs 30 33 FormTest
Upvotes: 2
Views: 2893
Reputation: 114631
VB.NET will allow you to do "Late Binding" (when option strict
is not used or when it's explicitly allowed through the project properties.) which will let the runtime check whether the object has a certain method before callign it. This is also possible in C#, but then you need to explicitly tell the runtime you want to allow this. You do it by marking the object as dynamic.
dynamic myDllClass = assmb.CreateInstance("myNamespace.myClass");
Dynamic will solve your direct issue, but it comes at a cost:
But a better solution would be, if you know the type of the class (which you do in this case, to cast it to that type (or to an Interface implemented by the class or a base class which your class extends from):
myClass myDllClass = (myClass) assmb.CreateInstance("myNamespace.myClass");
This would require you to add an assembly reference to the project containing the myClass
class.
You can improve your model by creating a shared assembly that contains the base class or interface:
In the shared assembly:
public interface myInterface
{
string publicConString { get; };
DataTable MethodReturnsDatatable(string sql, string connectionString);
}
In your file.dll
, add a reference to the assembly/project containing myInterface
:
public class myClass : myInterface{}
In your project consuming myClass
also add a reference to the assembly/project containing myInterface
:
myInterface myDllClass = (myInterface) assmb.CreateInstance("myNamespace.myClass");
This way you don't need to have a direct reference to file.dll
, allowing you to load different implementations at runtime, but it does ensure that you're only calling proper methods and that your code knows how to deal with it.
Upvotes: 5