Putting Web snapshots to practical use
September 28th, 2008
I was always interested if the service that, for example, WebSnapr provides is practically useful. Having snapshots of a linked pages looks very cool indeed, but does not really provide much information, at least for me.
But recently I have found a nice use case for a similar service. For tables in my IoC Frameworks posts, I was using parts of a Zoho spreadsheet embedded through an iframe. However, Google Code wikis do not allow iframe embedding.
The easy solution was to use built-in wiki table markup, but in this case I would lose all color coding and ability to download the whole sheet as Excel. The interesting solution was to embed snapshot of an iframe, as an image. This would also allow me to solve the iframe problem for RSS readers that do not support them.
My original idea was to use Firefox or Chrome (via Chromium project) to do the snapshots, but I have not managed to use the Mono.Mozilla on Windows and I was too lazy to dive into Chromium.
IE was the simplest remaining choice, so using information from the great article of Peter Bromberg, I have built my own implementation of web snapshotting service. The main difference between my snapshots and other services is that my service can actually determine the correct size of the snapshot.
For example, this is a snapshot of my IoC frameworks table:
You can click it to see the source of the snapshot. As you can see, it has correct size (instead of being fixed to 1024×768 or another screen size). On an unrelated note, it is an updated version of framework comparison, now including LinFu (which was updated to pass all feature tests).
In Google Code it looks like this.
Additional interesting usage for this would be iframe-widget embedding to locations that do not support iframes. For example, it is possible to embed a list of RSS feed headers or twitter messages in Google Code using this technique.
You can svn-download source code from Google Code. It is really bare for now, no good error-handling and no resizing support (all snapshots are always displayed in full size). However it may be a good starting point.
Looking at this project, I think that it would be very interesting to have a .NET wrapper for Chrome APIs that would allow anyone to automate Chrome, which probably will make snapshot extraction much faster and not COM-reliant.
DI Framework Challenges, 2: Lists
June 26th, 2008
There is another feature that I do not find in the dependency injection frameworks I’ve seen — list injection.
For example, let’s suppose you have a kind of a notification service that sends messages using all possible delivery providers. It makes sense to have a list of these in the service:
public class NotificationService { private readonly IDeliveryProvider[] providers; public NotificationService(IDeliveryProvider[] providers) { this.providers = providers; } public void SendAll(INotification[] notifications) { var deliveries = from notification in notifications from provider in providers from delivery in provider.GetDeliveries(notification) select delivery; this.DeliverAll(deliveries); } }
Now the problem is that there is no out-of-the-box support for such things in Castle, which is somewhat unexpected.
Yes, I can set arrays through configuration. But I never use XML configuration unless there is an extremely important reason for this to be configurable at deployment time, which does not happen very often with IoC containers. Also, documented approach implies that I have to hardcode a list of specific services here, which makes it a change preventer.
So configuration-only solution is out of the question.
Fortunately, in contrast with previous challenges, it is possible to implement this myself. There is a minor problem — Castle feature for getting an array of services (kernel.ResolveServices) is generic-only in RC3. But if I have to choose between hackarounds and using nameless trunk version, I prefer trunk version.
There is a naive version of the resolver:
internal class ListSubDependencyResolver : ISubDependencyResolver { private static readonly HashSet<Type> SupportedInterfaces = new HashSet<Type> { typeof(IEnumerable<>), typeof(ICollection<>), typeof(IList<>) }; private readonly IKernel kernel; public ListSubDependencyResolver(IKernel kernel) { this.kernel = kernel; } public bool CanResolve(CreationContext context, ISubDependencyResolver parentResolver, ComponentModel model, DependencyModel dependency) { if (parentResolver.CanResolve(context, parentResolver, model, dependency)) return true; var targetType = dependency.TargetType; if (targetType.IsArray) return true;
return targetType.IsInterface
&& targetType.IsGenericType
&& SupportedInterfaces.Contains(targetType.GetGenericTypeDefinition());
} public object Resolve(CreationContext context, ISubDependencyResolver parentResolver, ComponentModel model, DependencyModel dependency) { if (parentResolver.CanResolve(context, parentResolver, model, dependency)) return parentResolver.Resolve(context, parentResolver, model, dependency); var type = ( from @interface in dependency.TargetType.GetInterfaces() where @interface.IsGenericType && @interface.GetGenericTypeDefinition() == typeof(IEnumerable<>) select @interface.GetGenericArguments().First() ).Single(); return this.kernel.ResolveAll(type, new Hashtable()); } }
Side note: here we can see two minor problems with API design — first one is the mysterious parentResolver (what should I pass as parentResolver to parentResolver?), second one is that shiny new ResolveAll has no overload for the case when I do not need additionalArguments.
This is a very naive implementation (no checks if I can actually resolve generic parameter), but it works quite well with the original case (as well as with the other IList/ICollection/IEnumerable requirements).
However, there is a logical consistency problem with Singletons — they will get different parameters depending on whether you have resolved them before registering all their dependencies or after. If a Singleton has such dependencies, it can not be Startable, unless you make sure to register all dependencies before it.
I have found almost no information on using lists with DI, so I am not sure how others solve this. But I do not need Startable and all my components are registered at almost same time, so this is not a problem for me for now.
Update: Thanks to Victor Kornov, I have found a this post by Castle developer, which describes the same solution. I have added a proposition to the corresponding Google Group to make it a built-in feature. I prefer it being enabled by default, but I would like to see it either way.
Mocking internal interfaces with Moq
May 9th, 2008
Is a same method you would use with NMock2, but with “DynamicProxyGenAssembly2″ in InternalsVisibleTo.
This strange name is a default dynamic assembly name used by Castle.DynamicProxy.
Do not forget that the attribute should be added to the assembly with internal types, not to the tests assembly (obvious, but I got it wrong the first time).
Update: yesthatmcgurk has pointed me to the fact that for strongly named assemblies you have to specify the public key as well. So the correct attribute for the strongly named assembly should be
[assembly:InternalsVisibleTo("DynamicProxyGenAssembly2, PublicKey=002400000480000094000000060200000024000052534 1310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b 3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d926665 4753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb 4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c486 1eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7")] // without line-breaks
Metaprogramming in JavaScript: Auto properties for ASP.NET AJAX
October 8th, 2007
Sometimes, large company is no better than several independent companies.
I always get this thought when looking at ASP.NET AJAX property accessors.
For people not familiar with the matter:
Microsoft ASP.NET AJAX requires developer to use property accessors to encapsulate javascript fields.
This would be a great idea, if only Microsoft IE supported javascript getters and setters.
Mozilla supports them, and Opera will in 9.50, but IE does not (they are not standard).
Also, IE does not have any hacky way to achieve the same effect (except in VBScript, which seems to be limited).
So in ASP.NET AJAX each property requires two functions named get_propertyName and set_propertyName.
Fortunately, javascript is very powerful in class member manipulation.
So I do not have to write things like this:
MyControl.prototype = { get_text : function() { return this._text; }, set_text : function(value) { this._text = value; } }
And I do not have to wait for auto properties as it is the case for C#.
Instead I just made an helper object named Auto and do things this way:
MyControl.prototype = {…} Auto.properties(MyControl.prototype, [ 'text', 'value', … ]);
Code for this helper can be very simple.
(in actual project I have additional complexity like Auto support for INotifyPropertyChanged).
var Auto = { property : function(prototype, name) { var getter = function() { return this['_' + name]; }; prototype['get_' + name] = prototype['get_' + name] || getter; var setter = function(value) { this['_' + name] = value; }; prototype['set_' + name] = prototype['set_' + name] || setter; }, properties : function(prototype, names) { names.forEach(function(name) { Auto.property(prototype, name); }); } }
This also requires forEach method on Array, but that one is pretty obvious.
I like to show this code when I hear about Javascript being assembly language and whatever-to-javascript compilation.
CSS container class trick
October 8th, 2007
Recently I had a debugging session with one of my colleagues and I remebered a simple trick I use often.
Imagine that you have a list of items, and you want to simultaneously change them in response to a user action.
For example, what if you have this list:
<ul class="Contacts"> <li>Andrey <span>Shchekin<span></li> <li>Nina <span>Philippova<span></li> <li>Gordon <span>Freeman<span></li> </ul>
And you want to show/hide (expand/collapse) all spans in javascript.
One way to do this would be to go through all spans and change their className.
But that can be quite slow on large list.
The better way is to use something like addClassName (from prototype.js) on <ul>
.
So you change it to <ul class="Contacts AllCollapsed">
and then apply styles to .AllCollapsed li span
.
This way the browser is responsible for finding all contained elements, which should be faster.
Also, if elements are added dynamically, you do not have to process them.
Evaluating Javascript in WatiN
September 5th, 2007
The WatiN framework is quite cool, but it lacks two important things.
First one is searching by CSS selectors, or, at least, classes.
Find.ByCustom(“className”, “X”) is way too ugly. Or am I missing something?
The second (more important) one is a weak access to Javascript.
First thing I wanted to do with WatiN was to change something and then check some script state.
And getting some values from script was not obvious.
I didn’t want to use Ayende’s evil hack (no harm intentended, it gets the work done) — putting javascript state into DOM is not pretty and too string oriented.
I thought that browser COM interfaces should definitely have a way to get Javascript objects outside, that is just the way MS/COM people think.
Thanks to Jeff Brown’s comment for explaining last obstacles.
So here goes the code.
It is quite basic, but it allows you to get value of any Javascript evaluation.
As you can see, I hadn’t included any error handling, I had no time to look into it.
public static class JS { public static object Eval(Document document, string code) { IExpando window = JS.GetWindow(document); PropertyInfo property = JS.GetOrCreateProperty(window, "__lastEvalResult"); document.RunScript("window.__lastEvalResult = " + code + ";"); return property.GetValue(window, null); } private static PropertyInfo GetOrCreateProperty(IExpando expando, string name) { PropertyInfo property = expando.GetProperty(name, BindingFlags.Instance); if (property == null) property = expando.AddProperty(name); return property; } private static IExpando GetWindow(Document document) { return document.HtmlDocument.parentWindow as IExpando; } }
Nitpicking:
By the way, Ayende, getting permalinks to comments in your blog is not obvious (I used View Source).
Mocking internal interfaces with NMock2
July 7th, 2007
Yesterday I stumbled into a question of how to mock an internal interface.
The interface is visible in the test assembly due to InternalVisibleTo attribute, but Mockery was unable to create a mock of it.
The very first idea was additional InternalVisibleTo, but I had to find out what assembly name to use.
Since dynamic mocks are actual classes created on-demand for the specified interface, they do not belong to NMock2 assembly.
But they have their own dynamic assembly with consistent name — in case of NMock2 it is “Mocks” (I got it from Reflector).
So I used InternalVisibleTo(“Mocks”) and it actually worked.
I am not sure if it would work with strong names, but, fortunately, I do not need to strong name this project.