In order to define a type at compile time, you must reference the assembly that contains the type at compile time. If you are binding at runtime, you cannot define an item of that type. If you are loading the type at runtime, you must reflect against it to use it.
There are some options that may help you, however.
I suggest you extract an interface from your runtime bound type and put that in a separate assembly that you can bind against at compile time. You can then declare a variable of that interface and work against it without reflection, using reflection only for the creation of the type.
For example:
// defined in MyFoo.Contract.dll, or something like that. Your code
// references this assembly at compile time.
public interface IMyFoo
{
// members
}
// defined in MyFoo.dll, or something like that. Your code loads
// this assembly at runtime. MyFoo.dll references MyFoo.Contract.dll
// at compile time.
public class MyFoo : IMyFoo
{
// class def
}
// elsewhere...
Assembly asm = AppDomain.CurrentDomain.Load(...);
object myFooInstance = asm.CreateInstance(...);
IMyFoo myFoo = (IMyFoo)myFooInstance;
Another option available in .NET 4 is to use duck typing with the dynamic
keyword. This will allow you to use myFoo.MyMethod() syntax on an item to which you do not have a compile time reference.
For example:
dynamic myFoo = asm.CreateInstance(...);
myFoo.MyMethod();
// bound at runtime, but the compiler will allow it! No nasty
// Invoke() calls.