Home >

Implementing EnrichWith(of StructureMap) with Castle

15. July 2009

UPDATE: This facility made its way into Castle Microkernel, with name OnCreateFacility. I also made it possible to specify more than one actions.

In one of Joshua Flanagan's recent post he mentioned about how they handle application configuration and I have to say that I liked their way. I also liked how SM can post-modify an object created, and looked for a way to do it in Castle. As many other stuff, I was able to achieve the same effect with a custom Facility.

If I go further in the details, I had to catch ComponentCreated event of Kernel.

public class EnrichWithFacility:AbstractFacility
{
	public const string ExtendWithPropertyKey = "extendwith";
	protected override void Init()
	{
		Kernel.ComponentCreated += Kernel_ComponentCreated;
	}
	void Kernel_ComponentCreated(ComponentModel model, object instance)
	{
		if(model.ExtendedProperties.Contains(ExtendWithPropertyKey))
		{
			var action = model.ExtendedProperties[ExtendWithPropertyKey] as ExtendComponentDelegate;
			action(this.Kernel, instance);
		}
	}
}

Whenever a component is created, I will catch it and ask if there is any EnrichWith registered for the ComponentModel, and if there is any, invoke the action.

I also added a fluent registration extensions (Castle style!) in order to make it easy to register enrichments.

container.Register(Component.For<IService>().ImplementedBy<MyService>()
			 .EnrichWith((kernel, instance) => ((IService) instance).I++));

 

The code for the facility, fluent registration interface,and the tests can be found on our never-ending blog engine, BlogSharp codebase.

, ,

Comments

7/15/2009 1:53:35 AM #
This is a nice addition, and it should be in the core framework. Why the heck do you have to cast instance to the IService? It should be inferred from generic parameter of For<T>()
7/15/2009 1:57:21 AM #
There will be a problem with casting.

var action = model.ExtendedProperties[ExtendWithPropertyKey] as ExtendComponentDelegate;

We don't know the generic type here, it can be taken from the Component model and then we can invoke typeof(ExtendComponentDelegate<>).MakeGenericType() etc but didn't want to make it ugly.
7/15/2009 2:09:07 AM #
ha!

Long live generic variance ay?

You could keep this not as delegate but as simple wrapper generic class with not generic base type

public abstract class AbstractWrapper
{
public abstract void Invoke(IKernel kernel, object component);
}

public class Wrapper<T>:AbstractWrapper
{
private FooDelegate<T> method;//set in the ctor by the EnrichWith impl.

public void Invoke(IKernel kernel, object component)
{
   method(kernel, (T)component);
}
}

you create derived class instances, but refer to them via base type.

Should work.
7/15/2009 3:31:06 AM #
I like it. Another reason to use the Castle stack on my next project.. and maybe StructureMap too.
10/12/2010 11:00:08 AM #
thanks for posting this great article i really enjoy reading your post keep on posting i cant wait for new updates
12/6/2010 10:50:10 AM #
dispenses use a terrific web site decent Offers cheers for the exhausting work to assist folks*-*
12/6/2010 11:15:56 AM #
Your article very good, I am very interested in your story! *_*
12/9/2010 4:12:23 AM #
The web log really is wonderful.  I like reading through it but the truth is, the writing appears to be kinda odd when using the safari website broswer
12/29/2010 7:45:11 AM #
Interesting blog. It would be great if you can provide more details about it. Thanks you.
1/13/2011 11:39:29 AM #
Thanks for the set of codes.
3/22/2011 7:17:20 PM #
This article is good but I disagree with some certain points in it. Oh well, I am not a complete expert on the matter.  Thanks for the article anyways.
3/22/2011 7:17:36 PM #
I see there is some very good information in this article. Please continue with the work that you are doing
3/22/2011 8:20:38 PM #
This article is good but I disagree with some certain points in it. Oh well, I am not a complete expert on the matter.  Thanks for the article anyways.
3/23/2011 12:12:31 AM #
I think this is among the most important info for me. And i am glad reading your article. But wanna remark on some general things, The web site style is perfect, the articles is really nice : D. Good job, cheers
3/23/2011 11:41:02 AM #
Apple now has Rhapsody as an app, which is a great start, but it is currently hampered by the inability to store locally on your iPod, and has a dismal 64kbps bit rate. If this changes, then it will somewhat negate this advantage for the Zune, but the 10 songs per month will still be a big plus in Zune Pass' favor.
3/23/2011 4:20:40 PM #
i like your site, thank you for all sharing!
Comments are closed