Suppose I have three projects in my sln.
(1) xyz.a{Class Lib}{no reference added}
(2) yzx.b{Class Lib}{added the reference of xyz.a}
(3) zxy.c{Console App}{added the reference of xyz.a}
Now, I need to create the instance of a class residing in yzx.b from within xyz.a using reflection.
And also this should be independent of the folder/directory-names.
I.e. even If I change the name of the directory of yzx.b, it should work.
Does anyone have any idea?
First of all, Activator.CreateInstance() is a right way.
But, there is a more interesting way that is:
Just create expression that calls constructor:
public static Func<object[], object> CreateConstructorDelegate(ConstructorInfo method)
{
var args = Expression.Parameter(typeof(object[]), "args");
var parameters = new List<Expression>();
var methodParameters = method.GetParameters().ToList();
for (var i = 0; i < methodParameters.Count; i++)
{
parameters.Add(Expression.Convert(
Expression.ArrayIndex(args, Expression.Constant(i)),
methodParameters[i].ParameterType));
}
var call = Expression.Convert(Expression.New(method, parameters), typeof(object));
Expression body = call;
var callExpression = Expression.Lambda<Func<object[], object>>(body, args);
var result = callExpression.Compile();
return result;
}
Performance test:
public void activator()
{
var stopwatch = new Stopwatch();
const int times = 10000000;
stopwatch.Start();
for (int i = 0; i < times; i++)
{
var v = Activator.CreateInstance(typeof (C));
}
stopwatch.Stop();
Console.WriteLine(stopwatch.ElapsedMilliseconds + "ms with activator");
var del = CreateConstructorDelegate(typeof(C).GetConstructor(new Type[0]));
stopwatch = new Stopwatch();
stopwatch.Start();
var args = new object[0];
for (int i = 0; i < times; i++)
{
var v = del(args);
}
stopwatch.Stop();
Console.WriteLine(stopwatch.ElapsedMilliseconds + "ms with expression");
}
Output:
1569ms with activator
134ms with expression
But:
Just for curious.
You might want to check out the Activator.CreateInstance() methods. Just pass it the name of the assembly and type.
If you don't have a compile-time reference to the assembly, you can still reference it at runtime with Assembly.Load().
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With