Extract Method Info from DLL(managed code) and export to web service code






3.82/5 (10 votes)
Use reflection to extract information from DLL and generate web service code
Introduction
I had once encounter a problem in one of my project, in which, during the project development phase, I had a DLL which consists of hundred over classes and thousand of methods need to migrate to webservices. Base on the amount of methose and classes that the DLL consists, doing a manual job of creating the DLL interface and calling it via the webservices, apparently, will be a very tedious job indeed and easy to make mistake as well.
In order to solve my problem I had came out a tools. In particularly, it will extract the namespace, classes, and parameter information
from the specified DLL and showing it in a hierachical way. I could then, make use of these information and generate the webservices code. For better Illustration, I would like to describe the features of the tool as shown on the screen shot above. The usage of each item label by number is descibe in below.
- Click this button to locate for the DLL (written managed code)
- Click the load button and extract the information from the DLL
- Once the process done, all the namespace and classes information will be showing in this datagrid.
- Method information belongs to the selected classes in (3) will be showing in this datagrid.
- Parameter information for the selected method in (4) will be showing here.
- Summary Info for total of namespace, classes and method
- using Namespace ( in which you can just copy and paste it on any code that make use of the DLL
- Click on any row in datagrid(4) , a sample code of the going to be web method will be displayed.
- Select a few classes and method in (3) & (4), click on 'Start extract selected Method' will generate code in column (10)
- All the auto-generated web methods for the selected classes and method will be displaying here. The web method is categorized into region base on class name and name space. Copy and paste these code to the web services project.
Background
The basic idea for the tools is basically divided into 3 parts.
- making use of
system.reflection
and load the assembly and types. - A dataset with 3 tables,which will store the class, method and parameter make use by each method respectively. I provided also a boolean field which will keep tract of the user option whether to export this method to webservice or not.
- A method to generate code of calling interface in web service method.
- A Loop for method in (iii) to exported all the user selected method to web service method.
Using the code
The source code provided below is a method name call RetrieveClassInfo
. This method will retrieve all the class, method and parameter from the specified DLL. The below method will:
- Make use of
System.Reflection
- Call
Assembly.LoadFile
- Retrieve every exported types
- Loop through every exported type to retrieve methods in each types ( we might as well retrieve the member information to exclude out property method)
- Loop through every methods to retrieve parameter detail.
During the iteration, all the namespace, class, method and parameter information
will be extracted out and stored in a single dataset
.
//
// Any source code blocks look like this
//public void RetrieveClassInfo(string strFilePath)
{
...
Assembly AsmJ = Assembly.LoadFile(strFilePath);
Type[] types = AsmJ.GetExportedTypes();
...
foreach(Type t in types)
{
...
//REMARK : GetMethods will retrieve only public
//method, protected type is not listed
MethodInfo[] methodJ = t.GetMethods();
MemberInfo[] MymembeM = t.GetMembers();
//collect all the property method, For example,
//UserName is a property
//but get_UserName and set_Username is exist in the
//method name
//We do not wish to incluse the get_,
//set_ property method
//in the exported code
this.CollectPropertyMethod(ref al_PropertyMember,
ref MymembeM);
foreach(MethodInfo m in methodJ)
{
...
ParameterInfo[] myParams = m.GetParameters();
foreach(ParameterInfo pi in myParams)
{
...
}
}
}
}
There are some validation done along the iteration, such as
- identify the static method.
- identify standard class method like
GetHashCode
,GetType
,ToString
... (we will excluded out these method and will not stored in the dataset) - identify method that belongs to property, for instance, if the class consists of a property called
Property1
, thegetmethods()
will retrieveget_Property1
,set_Property1
as method in the assembly.
After all the information had been extracted and stored in the dataset, we would need a specific method to generate the web method code.
public string ExportSingleMethod(string strClassName,
ref udt_MethodViewInfo udt_MethodView)
The method name ExportSingleMethod will be majob part for the code generation. In which it need to identify the following issues:
- what is the return type of the method. For example, if "System.Void", we have to return as "void"
- The paramater type, position, and is it pass by reference
- Some of the parameter
System.Datarow
is pass by reference by default even without the keyword "ref" in the declaring statement.
Points of Interest
There a lot of validation need to take note when read from the DLL. I had listed out a few here.
- we have to make sure type is a class type is allow to proceed and namespace is not null.
foreach(Type t in types) { if(!t.IsClass) continue; ... strNameSpace = t.Namespace; if(strNameSpace == null) continue; ... }
- I had mentioned in the previous paragraph, any property will happens to have 2 public method prefix with "get_" and "set_" when we retrieve via GetMethods. The following code will do some checking to find out whether a particular methods is belongs to a property.
public bool CheckIsProprtyMethod(ref udt_MethodViewInfo udt_MethodView, ref ArrayList al_PropertyMethod) { string strFirst_Four; string strMethodName; strFirst_Four = udt_MethodView.strMethodName.Substring(0,4); if(!(strFirst_Four == "get_" || strFirst_Four == "set_")) //Definitely not a property method return true; strMethodName = udt_MethodView.strMethodName.Substring(4); for(int i=0; i< al_PropertyMethod.Count; i++) { if(strMethodName == al_PropertyMethod[i].ToString()) return false; } return true; }
- Upon retrieving method information, your will find out that there are methods like,
GetHashCode
,ToString
,GetType
,Equals
which is a standard method derived fromSystem.Object
. I have to excluded out this type of method when I exported it out to web services, i choose to compare with the method declaring type(namespace + classname) to make sure they are originally declared from the same class.public bool CheckForMethodWithSameDeclaringType(string strMethod_DeclaringType, string strNameSpace, string strClassName) { string strLookForDeclaringType; strLookForDeclaringType = strNameSpace + "." + strClassName; if(strMethod_DeclaringType == strLookForDeclaringType) return true; return false; }
- Some of the parameter type had a "&" at the end to indicate it is a pass by reference type. When export this type of the source code, i use the following method to get rid of the the ampersand
private string GetRidOf_Last_Ampersand(string strOriginal) { string strResult = ""; if(strOriginal[strOriginal.Length-1] == '&') strResult = strOriginal.Substring(0, strOriginal.Length-1); else strResult = strOriginal; return strResult; }
- The parameter type and return value is stored as full description with namespace included. Such as "double" is indicated as "System.Double", "int" as "System.Int32", we have to convert it to the short form by calling the below method.
private string ConvertToShortForm(string strOriginal) { if(strOriginal.Trim() == "") return strOriginal; string strResult = ""; // define which character is seperating fields char[] splitter = {'.'}; string[] strSplited = strOriginal.Split(splitter); strResult = strSplited[strSplited.Length-1]; return strResult; }
- After had been done, a short name is parameter or return type is achieved, somehow we prefer to see "double" rather than "Double" in our code generation, even though the compiler will still fine with it. User the following method to convert to the keyword that we wish to.
private string ConvertToSyntaxCorrectKeyword(string strOriginal) { switch(strOriginal) { case "Void" : return "void"; case "Int32" : return "int"; case "Boolean" : return "bool"; case "String" : return "string"; case "Double" : return "double"; case "Decimal" : return "decimal"; case "Object" : return "object"; case "Int32[]" : return "int[]"; case "String[]" : return "string[]"; //Add more base on your need default: return strOriginal; } }
Hope you find this tool useful.
History
None.