2009-09-13 6 views
2

내 프로젝트에 3 개의 프로젝트가 있다고 가정합니다.리플렉션을 사용하여 클래스 인스턴스화

(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} 

이제 반사를 사용하여 xyz.a 내에서 yzx.b에있는 클래스의 인스턴스를 만들어야합니다.

또한 폴더/디렉토리 이름과 독립적이어야합니다.

e.e. 심지어 yzx.b 디렉토리의 이름을 변경하더라도 작동 할 것입니다.

아무도 아이디어가 있습니까?

+1

JMSA, 관심있는 단어, __if__ 이것은 DAL/순환 의존성 문제에 관한 것입니다. 다른 질문은 도로에서 더 멀리 나아가고 있습니다. –

+0

@Henk Holterman, 누군가 나에게이 사실을 알리라는 것을 알고있었습니다. 하지만 내가 뭘 할 수 있을까? – anonymous

+0

@Henk Holteman, http://stackoverflow.com/questions/1415911/unable-to-get-data-from-da-layer-what-to-do이 문제를 해결할 다른 방법은 없습니다. – anonymous

답변

10

우선 Activator.CreateInstance() 은 올바른 방법입니다.

그러나, 인 더 재미있는 방법이 : 빨리

  • 10 배

그냥 생성자 호출 표현식을 작성 TargetInvocationException에 예외를 포장하지 마십시오가 :

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; 
} 

성능 테스트 :

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"); 
    } 

출력 :

1569ms with activator 
134ms with expression 

그러나 :

  • C# 3.0 만
  • 컴파일해야()는 그냥 호기심에 대한 장기 실행 작업

입니다 .

+0

"우선, Activator.CreateInstance()는 올바른 방법입니다". 이 의견은 무엇입니까? – anonymous

+0

u가 http://stackoverflow.com/questions/1415911/unable-to-get-data-from-da-layer-what-to-do 에 대해 이야기하고 있습니까? – anonymous

6

Activator.CreateInstance() 방법을 확인하시기 바랍니다. 그냥 어셈블리 이름을 입력하고 입력하십시오.

어셈블리에 대한 컴파일 타임 참조가없는 경우에도 런타임에 Assembly.Load()을 사용하여 참조 할 수 있습니다.

관련 문제