Archive

Archive for June, 2010

MirrorMirror: Working on the generics API

June 12, 2010 2 comments

Yesterday I finished the basic invokation API for MirrorMirror. Now I want it to start supporting generic methods. Since the current API uses params object[] for the parameters, I don’t know how to add the type parameters to that. I want to avoid the usage of generics in the API, because several times you will be dealing with internal types, so you can’t add them as a type parameter.

One idea I have is to change the current, simple API:

var result = object.Invoke("Method", arg1, arg2);

to

var result = object.Member("Method").Invoke(arg1, arg2);

so I can add method to that chain to support generics:

var result = object.Member("Method").Generic( type1, type2).Invoke(arg1, arg2);

Following this schema, I can always give support to the first API, but it will only work for non generic methods.
Also I would like to add support to generic types inference, so if you have a method with this signature:

private string MyGenericMethod<T1,T2>( T1 a, T2 b)
{
      ...
}

you can call it without specify the type parameters.

I will be working on this in the following days and will post the final thoughts.

Advertisements

ASP.NET WebForms LazyPanel: Dealing with output cache

June 4, 2010 Leave a comment

In a previous post I introduced you LazyPanel. Now I will talk about how it deals with output cache.
The main problem with output cache is when the cached response is retrieved, the content key is expired:

  • Request comes
  • Server processes the request
  • LazyPanel caches for 3 seconds it’s content and generates a key
  • Server returns the response without the lazy content but with an ajax call for retriving it
  • Request comes for the content with the generated key
  • Server returns the content and removes it from the cache
  • A new Request comes
  • Server retrieves it from the output cache
  • Reqeust comes for the content with the previously generated key
  • Server crashes because the key doesn’t exist 😥

Ideally, the content cache should take in care the same stuff that the output cache does, so instead of living 3 seconds, it lives the same time for the same circumstances. Well… “let’s see the code of the output cache” I said… and of course it is all sealed, internal and all the crap. F**k.

I opened the reflector and check the code. I realized that the output cache is stored in the web cache known by all of us and the key is generated using all output cache vars (params, encoding, etc). So, I copied (yes, copied) the strategy for creating the key and use it for storing the content cache. Finally, the duration of the cache is the same of the output cache and it seems to be working perfectly 🙂

MirrorMirror: Methods support/Api Improvements

June 3, 2010 Leave a comment

MirrorMirror now supports methods! The only restriction is the method can’t have more than 8 or 9 parameters (for void methods). This is because of the DynamicMethod working as a delegate and the need to have each Action and Func signature. Anyway, who needs 10 arguments in a method?

Also, I improved the API so you have only 3 main methods:

  • Get: Retrieves the value of the given fields and properties chain
  • Set: Sets the values of the field or property with the given name
  • Invoke: Ivokes the method with the given name that matches the given arguments
//Properties:
var name = person.Get<string>("Name");
person.Set("Name", "Ivo Wiblo");

//Fields
var name = person.Get<string>("_name");
person.Set("_name", "Ivo Wiblo");

//Methods
var name = person.Invoke<string>("GetName");
person.Invoke("SetName", "Ivo Wiblo");

//Chaining
var countryName = address.Get("City._country.Name");

ASP.NET WebForms LazyPanel: Deferred content loading in webforms

June 2, 2010 3 comments

One of the issues we face when developing a public website in webforms is the loading of contents asynchronously for improving the page load speed the user experiences. This is really common for MVC based applications, where each content could be retrieved from a different controller using AJAX, but for webforms it is a litte bit more complicated, especially if you already have the application working with all the events and postbacks and your users feels the application running slower because you are just loading too much information in one shot.

I faced this problem recently in an e-commerce like application where in the home page the most important thing is the search panel and the rest is just… “not so necessary” information. The application should take almost nothing to show the search panel and then start showing the contents, so the users can avoid waiting and just find whatever they want. Thinking about that with my friend and co-worker Javi, we got into a solution :).

The basic idea is to have a control that instead of rendering the html, renders a nice please wait and registers an ajax call that retrieves the content. This could be done in Webforms overriding the Render( HtmlTextWriter ) method.

Next we needed to store the original rendering somewhere, we chose a cache. Let’s see some code:

protected override void OnPreRender(EventArgs e)
{
	base.OnPreRender(e);
	var script = string.Format(ControlFormat, ClientID, Page.Server.UrlEncode(cacheKey));
	Page.ClientScript.RegisterStartupScript(GetType(), cacheKey, script, true);
}

protected override void Render(HtmlTextWriter writer) 
{
    string content;
    using (var stringWriter = new StringWriter())
    {
          using (var lazyWriter = new HtmlTextWriter(stringWriter))
                 base.Render(lazyWriter);

          content = new LazyContent(stringWriter.ToString(), remove, cache);
    }
            
    Page.Cache.Insert(cacheKey, content);
    
    RenderWaitImage(writer);
}

The js script requests an url like LazyContent.axd?key=, this is managed by an HttpModule that looks like:

public class LazyHandler : IHttpHandler
{
	public void ProcessRequest(HttpContext context)
	{
		var key = context.Request.QueryString["Key"];
		var content = (string)context.Cache[key]; 
		if (content == null)
			throw new LazyContentMissingException();

		context.Response.Write(content.Value);

		context.Cache.Remove(key);
	}

	public bool IsReusable
	{
		get { return true;}
	}
}

There’s an issue with the output cache, because for the cached responses the cached content won’t exist in the cache. In the following days I will be posting about how I handled that (don’t worry, it works!).

You can see the code here. It contains more features, like a loading delay, output cache support, etc.

EDIT: Source code updated with MirrorMirror newest version in order to remove the last classic reflection call.

Categories: C# Tags: , , ,

Mirror, Mirror on the wall

June 1, 2010 Leave a comment

Hi
It has been a long time since my last post. I moved to a new place and that keeped me busy these days (I even left Magiq for a while).

Well, I’m here to present you a new project I was working on. In fact, the source code was written inside of Magiq but I needed it for another project, so I decided to put it in a new project so I (and everyone) could use it easily. This is Mirror Mirror.

Basically, Mirror Mirror is a wrapper for IL operations related to accessing by reflection to objects members. The API is easier than regular reflection and it uses IL for generating delegates so it is several times faster.

For example, instead of

var name = typeof(Person).GetField("name", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(person);

you can do

var name = person.Property<string>("Name");

You can take a look at it in mirrormirror.codeplex.com.

Categories: C#, Mirror Mirror Tags: , ,