2012-07-26 3 views
5

SoapHttpClientProtocol 개체 (프록시 클래스)를 동적으로 인스턴스화하고이 개체를 사용하여 WS-Basic I Web Service를 호출하는 코드로 작업하고 있습니다. 여기에 내 코드의 단순화 된 버전입니다 :Activator.CreateInstance 대신 컴파일 된 람다 식을 사용하여 SoapHttpClientProtocol 개체를 초기화하십시오.

public override object Call(Type callingObject, 
string method, object[] methodParams, string URL) 
{ 
    MethodInfo requestMethod = callingObject.GetMethod(method); 

    //creates an instance of SoapHttpClientProtocol 
    object instance = Activator.CreateInstance(callingObject); 

    //sets the URL for the object that was just created 
    instance.GetType().InvokeMember("Url", 
    BindingFlags.Public | BindingFlags.Instance | BindingFlags.SetProperty, null, 
    instance, 
    new object[1] {URL}); 

    return requestMethod.Invoke(instance, methodParams); 
} 

나는 경우에 Activator.CreateInstance() 통화 시간의 상당한 시간이 걸릴 수 있습니다 것으로 나타났습니다, 그래서 나는 코드 by using a lambda expression 최적화하기 위해 노력하고있어 :

public override object Call(Type callingObject, 
string method, object[] methodParams, string URL) 
{ 
    MethodInfo requestMethod = callingObject.GetMethod(method); 

    //creates an instance of SoapHttpClientProtocol using compiled Lambda Expression 
    ConstructorInfo constructorInfo = callingObject.GetConstructor(new Type[0]); 
    object instance = Expression.Lambda(Expression.New(constructorInfo)).Compile(); 

    //sets the URL for the object that was just created 
    instance.GetType().InvokeMember("Url", 
    BindingFlags.Public | BindingFlags.Instance | BindingFlags.SetProperty, null, 
    instance, 
    new object[1] {URL}); 

    //calls the web service 
    return requestMethod.Invoke(instance, methodParams); 
} 

불행하게도이 코드는 callingObject 유형의 객체를 만들지 않고 대신 Func<T> 대리 객체를 반환하므로 다음 줄에 Url을 설정하려고 시도하면 예외가 throw됩니다.

System.MissingMethodException : 누락 된 멤버에 액세스하려고 시도했습니다.

코드에 뭔가가 누락 되었습니까?

감사합니다.

+0

링크가 길어 졌음 – NStuke

답변

3

Expression.Lambda(Expression.New(constructorInfo)).Compile() 부분은 callingObject 매개 변수에 저장된 Type의 생성자를 래핑하는 Func<T> 대리자를 반환합니다. 실제로 전화 그 생성자, 당신은 아직도 그것을 호출해야하지만

Delegate delegateWithConstructor = Expression.Lambda(Expression.New(constructorInfo)).Compile(); 
object instance = delegateWithConstructor.DynamicInvoke(); 

, 당신은 무엇을하려고하는 것은 장기적으로 매우 이상하고 깨지기 쉬운 것 당신은 간단한 문자열로 메소드 이름 주위에 전달되기 때문에 매개 변수를 객체로 사용하므로 모든 컴파일 타임 유형 검사가 손실됩니다. 왜 그것을해야합니까?

+0

+1 짧고 간단합니다. 하지만 왜 'Delegate'를 가져 가서 동적 호출을 수행합니까? 왜 그냥 'Func'을 누른 다음()? – nawfal

0

컴파일 된 표현식을 캐시하지 않으면 표현식 트리를 사용하면 프로그램이 더 느리게 실행됩니다.

관련 문제