2

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?

5
  • 1
    JMSA, just a word of concern, if this is about the DAL/Circular dependency problem from you other questions then you are getting further and further from the road. Commented Sep 13, 2009 at 21:31
  • @Henk Holterman, I knew someone would tell me this. But what else can I do? Commented Sep 13, 2009 at 21:42
  • @Henk Holteman, stackoverflow.com/questions/1415911/… there is no other way to solve this. Commented Sep 13, 2009 at 21:46
  • The answers on this question may point you to a better direction: stackoverflow.com/questions/1418277/… Commented Sep 13, 2009 at 22:02
  • Maybe you should decouple this projects and use something like StructureMap? Commented Sep 13, 2009 at 22:57

3 Answers 3

10

First of all, Activator.CreateInstance() is a right way.

But, there is a more interesting way that is:

  • 10 times faster
  • Don't wrap exceptions in TargetInvocationException

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:

  • C# 3.0 only
  • Complile() is long running operation

Just for curious.

Sign up to request clarification or add additional context in comments.

2 Comments

"First of all, Activator.CreateInstance() is a right way". What is this comment for?
5

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().

Comments

1

You can use Activator.CreateInstance to create an instance easily (this also does various caching of reflection information to make repeated calls faster), or Type.GetConstructor if you want to reflect over the constructor itself as well as directly running it (via ConstructorInfo.Invoke)

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.