Load Assembly

var typeAssembly = Assembly.GetAssembly(typeof(IMyInterface));
var callingAssembly = Assembly.GetCallingAssembly();
var entryAssembly = Assembly.GetEntryAssembly();
var executingAssembly = Assembly.GetExecutingAssembly();
var pluginAssembly = Assembly.Load("AssemblyName");

// Must use fully qualified name (including namespace) and cast to the target object:
var newInstanceByName = pluginAssembly.CreateInstance("MyNameSpace.MyClassName");

var interfaces = pluginAssembly.GetTypes()
    .Where(x => typeof(IMyInterface).IsAssignableFrom(x) && !x.IsInterface);
foreach (Type interfaceType in interfaces)
{
    var newInstance = Activator.CreateInstance(interfaceType) as IMyInterface;
    newInstance.Action();
}

Accessing Metadata Using System.Type

FieldInfo[] fields = myObject.GetType().GetFields(BindingFlags.Instance | BindingFlags.NonPublic);
foreach (var field in fields)
    if (field.FieldType == typeof(int))
        Console.WriteLine(field.GetValue(myObject));
int myNumber = 42;
MethodInfo compareToMethod = myNumber.GetType().GetMethod("CompareTo", new Type[] { typeof(int) });
int result = (int)compareToMethod.Invoke(myNumber, new object[] { 41 });

Member Invocation

PropertyInfo property = myObject.GetType().GetProperty("MyProperty",
    BindingFlags.IgnoreCase | BindingFlags.Instance | BindingFlags.Public);
if (property != null)
{
    if (property.PropertyType == typeof(bool))
        property.SetValue(myObject, true, null); // Last parameters for indexers
    else if (property.PropertyType == typeof(string))
        property.SetValue(myObject, "MyValue", null);
		Console.WriteLine(property.GetValue(myObject, "MyValue"));
}

Working with Generics

Type type = typeof(Nullable<>);
var hasGenericParameters = type.ContainsGenericParameters;
var isGenericType = type.IsGenericType;
Type[] genericArgumens = type.GetGenericArguments();