Comparing .NET DI (IoC) Frameworks, Part 1
August 19th, 2008
Having some spare time and interest, I decided to learn a bit more about the features of modern .NET IoC frameworks. Being aware of what’s available always helps, and I haven’t yet seen a comprehensive feature comparison.
For the comparison, I have selected the frameworks that I feel to be most documented and popular:
If you feel that your framework should be here, just send me the values for all feature columns, and I’ll add it.
0. Terminology
The first thing I learned is that common concepts are sometimes named differently between the frameworks.
So I think it makes sense to start with some terminology.
Components are classes registered within the container. They can be instantiated by the container to satisfy service dependencies of other components. Services are what components provides and depends on.
In most of the cases services are interfaces, and components are classes implementing them.
Autowiring is an automatic detection of dependency injection points. If the framework is able to match the constructor parameter types with registered services and provide these services, it is an example of autowiring.
Transient components, as compared to singletons, are created each time they are requested from container. The exact term used for transients differs quite much between frameworks.
Automatic registration is a way to automatically detect and register components within an assembly (or larger environment). It can also be called batch registration.
1. Licensing and core size
All reviewed frameworks work under .NET 2.0, and have liberal licenses allowing commercial and open-source usage.
The first table lists the reviewed frameworks with some basic parameters.
The color map is easy: green is great, yellow is ok, red is bad. All colors are extremely subjective, things bad for me may mean that I am doing something wrong.
I do not feel library count or size to be important for developments, so no red points this time.
Ninject is the most interesting case, since it has a very naive auto-wiring implementation by default. However, it has an official Ninject.Extensions.AutoWiring library, so in all following tables I included its features in Ninject functionality.
2. Container configuration
The first thing to do with container is to register something in it. So let’s review the configuration options provided by various framework.
As you can see, all frameworks support programmatic registration. Even better, most of them have fluent interfaces for registration API. Spring.Net and Castle are behind others in this regard, since Spring.Net API is somewhat cumbersome and not fluent, while Castle does not support fluent registration in RC3.
As I noted before, automatic registration is a way to register all types in given set of assemblies/namespaces based on attributes or other conventions. I find it very useful, since the convention-driven approach saves time on configuration and lessens a chance of a configuration error.
Castle’s BatchRegistrationFacility is obsolete and well-hidden, also it uses GetExportedTypes instead of GetTypes (The Sin of Shallow Digging), so it’s useless if you want to hide implementations and expose only interfaces. For Spring.NET I didn’t find an easy way, but it still might be possible, so you can correct me on this one.
Some people consider attributes to be POCO, some not, and I tend to agree with the latter when we are talking about DI frameworks. So no red points or yellow points if framework has no attributes, this column just for your information.
As for XML, I have a very strong opinion — only if actually needed, only as much as actually needed. Fortunately, no one of reviewed frameworks required XML (while most of them support it when needed). Spring.Net is somewhat differently oriented for this question, since its XML API is a better, more documented and encouraged approach. However, since Spring is a Java port, the approach is probably a compatibility heritage.
3. Basic injection/autowiring
The second thing after configuring the framework is knowing what exactly can be automatically injected. And, as I explained earlier, autowiring is just a name for framework-discovered injection points.
Basic constructor injection works great in all frameworks. For property injection Unity and StructureMap require explicit opt-in and treat the dependency as mandatory, which is a bit counterintuitive and does not provide any benefit over constructor injection.
As for multiple constructors, I really like the Castle/Autofac choice of constructor with most resolvable parameters. This is precisely what the human programmer will do, given a number of constructors and dependencies. With approach taken by Unity and StructureMap, it is harder to keep object DI-ignorant — you have to think whether your most-parameter constructor is resolvable, add DI-specific attributes or specify the constructor explicitly in the XML/code configuration.
The most interesting behavior was shown by the Spring.Net — it selected default (no-parameter) constructor first, and only if default did not exists, Spring went to the most resolvable.
Recursive dependency resolution is, in my opinion, one of the most important things in a DI framework. In a large project, when you have a lot of components and services, solving recursion easily is a must. In my tests only Castle and Autofac gave a useful error message, all other frameworks just crashed with unrecoverable StackOverflowException, which is a bad, bad thing to get in automatic test runner.
4. To be continued
In the second post of the series, I will review advanced features of DI containers (with StructureMap demonstrating unexpected feature), and show an automated feature tests I used to fill the blanks in these tables.
Some thoughts on ASP.NET AJAX Roadmap
July 19th, 2008
Coming from a vacation, I have just discovered a new ASP.NET AJAX roadmap. A post by Matt Berseth starts with a summary of discussion done so far.
I have some personal opinions on the question of ASP.NET AJAX since our team worked with it a lot. So I decided to write a post instead of just commenting existing discussion.
I think I have a slightly different approach to this framework, as compared to other posters. I do not have to choose jQuery/prototype/mootools over ASP.NET AJAX. It is obvious that chaining in jQuery makes life easier, and extending element whenever possible is also a friendly approach.
However, I will still use ASP.NET AJAX for the interoperability with ASP.NET architecture — I can have a JavaScript part for any control I have, and pass values between C# and JavaScript. Also the component lifecycle (being able to handle component references easily) is a large win for me.
What I do not like is the cumbersome get_/set_ requirement without a built-in shortcut (I described one solution earlier) and cumbersome event subscription.
Event Subscription
So, let’s start with this roadmap sample:
1: $query("textarea.rich")
2: .addHandler("focus", function(e) {
3: Sys.Debug.trace("focused into " + (e.eventTarget.id || "?"));
4: })
5: .setStyle("width", function() {
6: return (document.body.clientWidth — 10) + "px";
7: })
8: .create(Contoso.UI.RichTextBehavior, {
9: showToolbar: true,
10: fonts: ["Arial", "Times", "Courier"]
11: });
What we have now in our project for event subscription is similar to this
1: with (Auto.Events) {
2: when(textarea).gets('focus').call('textarea_got_focus').on(this);
3: when(list).has('changed').call(function() { alert('list_changed'); })
4: }
Which also alters dispose to remove the event handler (which is something very tedious to do manually).
So the thing I most dislike in new ASP.NET AJAX syntax is that it is not readable (just plain chaining). I see Event.Behavior as a beautiful solution, jQuery’s as acceptable one (not a language, just more precise naming shortcuts), and ASP.NET AJAX as not really usable.
Same goes to $listen — I just can not remember the correct order of arguments unless looking directly to the documentation or IntelliSense.
But I think that $listen is a great idea, and the solution should be very interesting (considering that IE does not support DOM mutation events).
Templates
Most popular post in my blog is about client-side databinding. I can not show a solution that we have built to solve this issue (we have built it specifically for a project which sources I can not show), so this post is somewhat useless.
I am very hopeful about ASP.NET AJAX’s UI Templates, but I am also thinking about several problems we encountered. The first one is performance — it is absolutely necessary to pre-cache template binding function. The second one is binding repeated template with server controls.
There is a sample in the roadmap document:
1: <!--* for (var i = 0; i < features.length; i++) { *-->
2: <span>{{ features[i].name }}</span>
3: <!--*
4: $create(Contoso.Tooltip, {
5: text: features[i].description
6: }, {}, {}, $element);
7: *-->
8: <!--* } *-->
but I am not sure if it is possible to do this:
1: <!--* for (var i = 0; i < features.length; i++) { *-->
2: <my:Label Text="{{ features[i].name }}" />
3: <!--* } *-->
where my:Label is a ASP.NET AJAX control. It was one the most complex problem for our client:Repeater, so I am interested if this would be implemented.
Now, in contrary to Matt Berseth, I am not really concerned with INotifyPropertyChanged, because it is extremely easy to write a meta-helper to auto-implement it for any given object or prototype in JavaScript.
What I am concerned with with is an idea to “expose methods such as insertRow” for Client DataSource. I do not have any rows in presentational model or my JavaScript arrays, so I strongly dislike this terminology.
The dream feature for me would be a Continuous LINQ for JavaScript, where you can dynamically bind to a dynamically filtered collection, bind to products.where(function(p) { return p.Cost > 5; }). We did a basic implementation for this kind of thing, and found it extremely useful for rich web application. You can have a live model behind a complex page, and never explicitly think of updating any part of the page when some collection in the model got changed.
Animation
I am not really interested in that — other frameworks do this kind of thing easier. And if ASP.NET AJAX is going to imitate jQuery syntax, as some people want, why not just use jQuery or mootools?
Other features
I think that built-in Drag&Drop may make my life easier, looking forward to it. Also, ASP.NET MVC integration has always been a must, it is nice to see it is coming.
All IDE changes are also very welcome.
Summary
In general, I like the proposed changes.
I have a feeling that Microsoft should add more meta helpers as Auto.properties. It is easy to do, but not obvious for the people who are not doing a lot of JavaScript. Also the auto-INotifyPropertyChanged and built-in ObservableCollection would fix databinding cumbersomeness in the same situation.
Also, I am interested in how are the specific technical challenges solved, but it too early to think about that right now.
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.
DI Framework Challenges, 1: Simple Factories
June 23rd, 2008
I am not sure what is the exact name for this pattern (probably Factory Method), but I often have a situation where I have to select a specific derived type based on some parameters.
For example, I may have a SyncFactory with CreateSync method that creates a Sync based on number of parameters.
public class SyncFactory { public ISync CreateSync(…) { if (…) return new FullSync(…); if (…) return new ExportSync(…); return new SimpleSync(…); } }
This is a simplest situation. Now a realistic case may require synÑ operations to depend on some services.
Ok, let’s put them into a DI container and resolve them:
public class SyncFactory { // IResolver abstracts specific DI implementation // and the fact we are using DI. It is also mockable. public SyncFactory(IResolver<ISync> resolver) { … } public ISync CreateSync(…) { if (…) return resolver.Resolve<FullSync>(); if (…) return resolver.Resolve<ExportSync>(); return resolver.Resolve<SimpleSync>(); } }
Up to now everything went quite smooth. But what if the factory needs to give some additional parameters to the syncs, like some SyncEndPoint?
With this in mind, I immediately stumble into two problems. First one is practical: how to pass parameters to the component being resolved? Second one is perfectionist: if components make no sense without these additional parameters, why should they be registered and available in a DI container?
I have been working with Castle IoC framework and I have found no good solution to both of these problems. First one can be solved by passing “additionalArguments” to Resolve methods, but this couples me to parameter names.
What I would like to do is to have some kind of local scope so I could do the following:
public class SyncFactory { public ISync CreateSync(…) { using (var endPoint = this.CreateEndPoint(…)) using (var scope = new ComponentScope(endPoint)) { if (…) return resolver.Resolve<FullSync>(); if (…) return resolver.Resolve<ExportSync>(); return resolver.Resolve<SimpleSync>(); } } }
For second one, it makes sense to have a Create<T>() method on the container that does not require T to be registered, but does the same constructor discovery/creation as it does for registered components. Otherwise, we have to register useless components in the container, which leads to container pollution.
Unfortunately, Windsor/MicroKernel does not have this feature.
I am still not sure whether it’s me doing something the wrong way or argument coupling and container pollution are considered not that big of a deal. For me they seem to be a good feature test for DI Framework, and I am yet to see one with these fixed.
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
Sins of .NET API Developers
March 25th, 2008
There are several annoying design flaws I often stumble into in .NET APIs.
I haven’t seen Design Guidelines on this matter, so I think I’ll point to 3 of these myself.
-
The Generic Sin
Do provide a non-generic overloads to generic utility methods.
Ayende already wrote about it, so it does not make sense to repeat the reasons.
Fortunately, this is a very rare issue.Violating framework: Castle.MicroKernel (DefaultKernel.ResolveServices<T>).
-
The Sin of Shallow Digging
Do support non-public members when performing type/member discovery.
Do not ever use Assembly.GetExportedTypes unless this logic can easily be overriden.For example, I like to make my Domain Service interfaces public, but keep implementations internal.
This means that if I use InternalsVisibleTo, I can unit-test implementations, but the clients must use interfaces.
But if I try to define a common generic test base class, and use it like XTest : TestBase<X>, then if X is internal XTest should also be.
Now neither MbUnit or TestDriven.Net see my test, regardless of TestFixture attribute.So if you use attributes to discover members automatically, the only reason to discard a member should be the absense of an attribute.
Access modifiers should not be considered, if the member does have an attribute.Violating frameworks: MbUnit, Castle.Facilities.BatchRegistration.
-
The Sin of Tivoization
For each public interface you create, think how user can inject his own implementation.
(If this interface is directly consumed by API public methods, you can skip this step).For example, let’s look at an interface MbUnit.Core.IFixtureFactory.
It is public, which seems good enough for people who hate internals.
But it is not possible to provide your implementation without wrapping the whole test-running engine.It’s a pity. The framework I am developing right now would really benefit from it.
Violating frameworks: MbUnit.
Unit Testing and the importance of naming
October 13th, 2007
Microsoft’s VSTS lacks RowTest and that’s why I will not use it.
But there is one thing about VSTS that is done right.
It is naming.
We use TestFixture so often, but what is it exactly?
Let’s go to wikipedia:
Test fixture refers to the fixed state used as a baseline for running tests in software testing.
The purpose of a test fixture is to ensure that there is a well known and fixed environment in which tests are run so that results are repeatable.
If I go and ask all developers I know, no one would be able to repeat this definition.
And it is why unit testing was really hard for me to understand.
TestClass and TestMethod are practical names that desribe what we want to do.
TestFixture is an academic name that describes what we are supposed to do.
It conveys the feeling that I should read a tome of obscure knowledge to get it.
While I am fine with reading, this time things just seem to be hard.
Take VB’s Shared versus C# static.
How many people you know understand why static keyword has this name?
But we still have to live without useful features just because of the name.
The moral of the story: naming is very important.
It can make things unnecesarily complex or decrease your agility in changing underlying behavior.
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.
NMock 3.5
September 23rd, 2007
One of the places where I am likely to actively use expression trees is testing/mocking.
(I am not the first one to notice this — I saw some post on expression tree asserts, but I lost it).
In my day-to-day development I am using NMock2.
Ayende‘s Rhino Mocks may be more convenient, but I do not like the syntax.
I just can’t read “expect call return” — my mind wants “expect call returns”.
Also, event support in Rhinos is really cryptic.
(I understand that it may be the only stringless way to express it).
So working on C# 3.0 project, I’ve looked into a stringless experience with NMock2.
What I wanted was to pass a method call expression, to change this:
Expect.Once.On(fs) .Method("GetDescendantDirectories") .With(RootPath) .Will(Return.Value(directories));
into this
Expect.Once .That(() => fs.GetDescendantDirectories(RootPath)) .Will(Return.Value(directories));
Fortunately, it was quite easy to do with extension methods.
I have spent more time figuring better fluent syntax than actually writing it.
But the case where expression trees really shine, I think, is in the possibility to do this:
Expect.Exactly(directory.Files.Count) .That(() => access.IsPublicFile(Any.String)) .Will(Return.Value(true));
I can analyze expression tree and find out that Any.String is not “a string”, but “any string”.
It is also easy to imagine Any.String.Matching(“^whatever”) and so on.
I have not tried to implement it, but I feel that it would be simple as well.
Also, while writing the post, I just got an idea — in the world of extenson methods we can do
Expect.Exactly(directory.Files.Count) .That(() => access.IsPublicFile(Any.String)) .Will.Return(true);
without sacrificing extensibility.
“Will” can also be chained if more than one action is needed (however, a delegate would be better for this).
It would be nice to actually add this to NMock2 (as 3.5 branch), but they are using CVS, not SVN.
Also, am I the only one who thinks that SourceForge is slow and has hardly usable (bloated) design?
So if you want the code, you can ask me in comments, but it is primitive indeed.