Thursday, May 28, 2009

BuildManager To Get Detail About Dynamic Compiled Assembly

Here i am going to explain how one can use BuildManager to get detail about dynamic generated Assembly.
In ASP.net 2.0 or ASP.net 3.5 , there are two type of projects. One is ASP.net Web Application and Another one is ASP.net WebSite Project. Significant difference between these two is how they compiled or published.

1. When “ASP.net WebApplication“ project published it create only Single DLL file in Bin for whole application and DLL name is also predetermined. Also when any new item added to the Project ( Either Web Form or Web User Control ) it comes under one namespace.

2. When “ASP.net WebSite“ project published then it create many DLL file in bin directory. No of DLL depend on condition you choose when publish “ASP.net WebSite” project.

image
- When only first checkbox is checked then it create assembly per directory. In following image you can see one sample solution. So it create one assembly for Top Level directory and their page and control and one assembly for TestControls directory.

       image

- When second checkbox is selected then it creates separate assembly for each page and each controls.

Now main thing “BuildManager” comes into picture. 

1. If you have “ASP.net WebApplication” project then you can access of another type in project via namespace. For Example you have two page "Default.aspx” and “Default2.aspx” and you want to just create instance of “Default.aspx” via its type in “Default2.aspx”.

namespace WebApplication3
{
    public partial class _Default : System.Web.UI.Page
    {
        public string GetMessage()
        {
              return “Hello”;
        }
        protected void Page_Load(object sender, EventArgs e)
        {
        }
    }
}

namespace WebApplication3
{
    public partial class WebForm1 : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        { 
            WebApplication3._Default dForm = new _Default();
            Response.Write(dForm.GetMessage());
         }
    }
}
so it is very easy for “ASP.net WebApplication” project.

2.  For “ASP.net Web site“ type of project this is not a case. This type of project does not allow you to access another simple way as above. For that you have to use BuildManager Class.

public partial class _Default : System.Web.UI.Page
{   
protected void Page_Load(object sender, EventArgs e)
{   
// You can not access Default2 class directly.    
// Get Type using BuildManager.
// Here i specified virtual path.

Type compiled_o =  System.Web.Compilation.BuildManager.GetCompiledType("~/Default2.aspx");                
//Detail about assembly. Fully qualified name which contain dynamic assembly name too.
Response.Write(compiled_o.FullName);
// Create instance of Type.
object obj =  Activator.CreateInstance(compiled_o);
// GetData is a Method to call.
System.Reflection.MethodInfo info = compiled_o.GetMethod("GetMessage"); 
// Now Call method . Here Method GetData is a instance method so we need to call
// Invoke method with obj. null as no argument required.
object data = info.Invoke(obj, null);
// Check that data contain value.
if (data != null)
{
  Response.Write(data.ToString());

}
}
public partial class Default2 : System.Web.UI.Page
{
    public string GetMessage()
    {
              return “Hello”;
    }
    protected void Page_Load(object sender, EventArgs e)
    {
    }
}

BuildManager class has static method GetCompiledType, which required virtual path as a input so you can even give virtual path of user control too.

Please give your comment on this.

No comments: