In order to instantiate a type ClassB
inside AssemblyB
from AssemblyA
where AssemblyB
is NOT a referenced assembly (but loaded with Assembly.LoadNnn
you can do the following:
- Load the Assembly via one of the
Assembly.LoadNnn
overloads
- Scan
DefinedTypes
of the loaded assembly to detect the type
- Use
Activator.CreateInstanceNnn
to instantiate the type
Here is some code that would do that for you:
using System;
using System.Reflection;
using System.Diagnostics.Contracts;
// this is AssemblyB
// residing at C:\TEMP\AssemblyB.dll
namespace Com.Example.SO12188029.AssemblyB
{
public class ClassB
{
public string Property { get; set; } = "tralala";
}
}
// this is AssemblyA
// residing at C:\SomeWhereElse\AssemblyA.dll
namespace Com.Example.SO12188029.AssemblyA
{
public class ClassA
{
private const string assemblyBPathAndFileName = @"C:\TEMP\AssemblyB.dll";
private const string typeFromAssemblyBToBeInstantiated = @"Com.Example.SO12188029.AssemblyB.ClassB";
public static void Main(string[] args)
{
// try to load assembly
var assembly = Assembly.LoadFrom(assemblyBPathAndFileName);
Contract.Assert(null != assembly, assemblyBPathAndFileName);
// make sure type exists in assembly
var type = assembly.DefinedTypes.First(e => e.IsClass && !e.IsAbstract
&& e.FullName == typeFromAssemblyBToBeInstantiated);
Contract.Assert(null != type, typeFromAssemblyBToBeInstantiated);
// try to get instance of type
var instance = Activator.CreateInstance(assembly.ManifestModule.FullyQualifiedName, typeFromAssemblyBToBeInstantiated);
// ... now we have an instance, but as long as you do not know what *kind* of instance this is
// you cannot do much with it, unless - we use reflection to get access to the instance
var propertyInfo = instance.GetType().GetProperty("Property");
var propertyValue = propertyInfo.GetValue(instance);
Console.WriteLine("ClassB.PropertyValue '{0}'", propertyValue);
}
}
}
However, this is actually very inconvenient to use, so you better use interfaces that are common to both assembly. With that you can cast your ClassB
to e.g. IClassB
and access its properties without falling back to reflection. And instead of using Assembly.LoadFrom
and Activator.CreateInstanceFrom
I would consider using StructureMap
so you can scan your assemblies and get an instance from it (though it might be considered an AntiPattern, but not doing more harm than Activator
itself).