- NHibernate 2.1.0 alpha 1 released, note that the dynamic proxy stuff has been changed so read the release notes.
- War stories from Joe Stump lead architect at Digg, very interesting!
- Roy Osherove reviews the tests from NerdDinner, interesting and funny. He also has a book out which I promptly ordered: The Art of Unit Testing: with Examples in .NET
- MIX, get a view on where Microsoft is going with Silverlight, .NET, ….
WCF ChannelManagement drop 2
Updated version is now available, no channel pooling yet but I changed the way default values and the ProductTemplate were being handled. I’ve already used the library successfully at work in a very heavy WCF application. I found some issues with it, like when you wanted to configure the ChannelFactory in your configuration file, but these are now fixed.
Next up pooling!
WCFChannelManager_drop2.zip (1.14 mb)
Series:
This week on my screen #4
- SOLID pictures, if you don’t know what it stands for visit this site.
- Manifesto for Software Craftsmanship.
- Windows 7 HTPC on Tom’s Hardware.
- Fluent NUnit.
- In depth article on BeginInvoke, Invoke. If you multithread your Winforms a must read.
- WCFMock, mocking for WCF, what’s in a name.
- SAML token with Geneva.
- Free eBook on ASP.NET MVC
First drop of ChannelManagement available.
First drop available of the ChannelManagement library. Currently only support single action channels, meaning that after executing the operation the channel is closed. I hope to add pooling the coming week.
The zip contains the source code and an example project. Not much changes in the ‘end user’ code:
static void Main(string[] args) { var myService = ContextRegistry.GetContext().GetObject("MyService") as IService1; string value = myService.GetData(5); var returnValue = myService.GetDataUsingDataContract(new CompositeType() { BoolValue = false, StringValue = "Perponcher" }); Console.ReadLine(); } |
<spring> <context> <resource uri="config://spring/objects" /> </context> <objects xmlns="http://www.springframework.net"> <object id="MyService" type="WCFChannelManager.ChannelManagerFactoryObject, Perponcher.WCFChannelManager"> <property name="ChannelType" expression="T(Server.IService1, Common)"/> <property name="EndpointConfigurationName" value="MyEndpoint"/> </object> </objects> </spring> <system.serviceModel> <client> <endpoint name="MyEndpoint" address="http://localhost:8731/Design_Time_Addresses/Server/Service1/" contract="Server.IService1" binding ="wsHttpBinding"/> </client> </system.serviceModel> |
Out and ref parameters are not yet supported.
WCFChannelManager.zip (1.17 mb)
Series:
This week on my screen #3
- NHibernate in Action is finally released.
- How FriendFeed used MySQL.
- NServicebus, a servicebus for .net.
- masstransit, another servicebus.
- Problems with WCF and the Using block on InfoQ, interesting for my little ChannelManager project.
- RestPad, editor for communicating with RESTful services.
Configuring the ChannelManager
I’m trying to keep configuration to a minimum. Let’s look at an example:
<object id="MyService" type="WCFChannelManager.ChannelManagerFactoryObject"> <property name="ChannelType" expression="T(WCFChannelManagerTests.IService)"/> <property name="EndpointConfigurationName" value="MyEndpointName"/> </object> |
This is probably what you’ll need the most. You define the ChannelType, that is the interface exposed by the service you want to consume, and the EndpointConfigurationName, which is the name of the endpoint in the system.servicemodel section of your app/web.config. And that’s it. The behaviour of the channel in this case is that a new channel will be created for every operation you want to execute.
<object id="MyService" type="WCFChannelManager.ChannelManagerFactoryObject"> <property name="ChannelType" expression="T(WCFChannelManagerTests.IService)"/> <property name="EndpointConfigurationName" value="MyEndpointName"/> <property name="ChannelManagementMode" value="Recycle"/> </object> |
If you want channels to be reused, you can specify this by changing the value of the ‘ChannelManagementMode’. There are two predefined values you can use here, Recycle and ThrowAway. ThrowAway being the default. Not sure about these names though :-).
<object id="OneTimeUseChannel" type="WCFChannelManager.SingleActionChannelManager<WCFChannelManagerTests.IService>"/> <object id="MyService" type="WCFChannelManager.ChannelManagerFactoryObject"> <property name="ChannelType" expression="T(WCFChannelManagerTests.IService)"/> <property name="EndpointConfigurationName" value="MyEndpointName"/> <property name="ProductTemplate"> <object> <property name="ChannelManager" ref="OneTimeUseChannel"/> </object> </property> </object> |
If one of the default ways to manage the lifecycle of a channel is not what you want or need you can create your own and specify it in the ProductTemplate property of the ChannelManagerFactoryObject. The example above shows how you can do this, in this case it would result in the same default behaviour you get in the first xml configuration I showed in the beginning of my post.
If you even want to customize the way a channel is retrieved, an action is executed on it and then handed back to the channel lifecycle manager, you can subclass ChannelActionWrapper and specify that type in the ChannelActionWrapperType property of the ChannelManagerFactoryObject. This is illustrated below:
<object id="MyService" type="WCFChannelManager.ChannelManagerFactoryObject"> <property name="ChannelActionWrapperType" expression="T(WCFChannelManagerTests.MockChannelManager)"/> <property name="EndpointConfigurationName" value="MyEndpointName"/> </object> |
public class MockChannelManager : ChannelActionWrapper<IService> { public MockChannelManager() : base(null) { } public override IService GetChannelToWorkWith() { return new Service(); } public object ExecuteOperation(MethodInfo info, object[] parameters) { return this.ExecuteInChannel(info, parameters); } } |
The ChannelType will now be retrieved from your subclass so you don’t need to specify the ChannelType.
And that’s all I have for you now.
Series:
This week on my screen #2
- WCF Extensions on CodePlex, features compression
- HTTP Chunking channel for WCF
- WS-Compression for WCF, compression!
- That last blog has more excellent material, something on which I did some research a while ago and still want to blog about: OpenId and OAuth on desktop applications.
A lot of WCF, since that’s what I’m doing at work for the moment. Still looking for a good book on it, if anyone has suggestions please let me know.
Oh yeah, I started tweeting. How fashionable.
This week on my screen #1
- Fluent NHibernate launches an official site and wiki.
- AutoMapper, an object-to-object mapper, maybe I can finally stop writing assemblers in my projects.
- Microsoft Geneva, enabling claim based applications, SSO for desktop apps perhaps.
- Mark Pollack talks about the Spring.Net roadmap on InfoQ, including a code based approach to configure your application.
- Custom authentication with Microsoft Geneva, shameless plug.
WPF Application by Billy Hollis
I had seen presentations by Billy Hollis before (via InfoQ) and ran into this one today. If you aren’t convinced what WPF can do for you, as WinForm developer, go check it out.
If you’re not into WPF, the site has much more interesting .Net material.
Mapping a list of components with Fluent NHibernate
This took me some time to figure out since documentation for Fluent NHibernate is still a little scarce. Let’s say we have an entity “ActivityType” which has an icon and a name, but the name is stored for each language so we have a one to many relationship. This relationship is not only modelled in the entity “ActivityType” but also in several others. The translation is modelled in the “LocalizedEntity” class. As illustrated in the class diagram below:
The DB is illustrated in the next diagram, to make it easy the tables have a different name compared to the entity diagram :p.
The mapping for the “Language” entity is pretty straightforward. The mapping for the “ActivityType” and its localizations was a bigger challenge since I got lost in all the delegates after the Component method.
public class LanuageMapping : ClassMap<Language> { public LanuageMapping() { Id(x => x.Id); Map(x => x.Name); WithTable("[7de_Languages]"); } } public class ActivityTypeMapping : ClassMap<ActivityType> { public ActivityTypeMapping() { WithTable("[7de_EventTypes]"); Id(activityType => activityType.Id); Map(activityType => activityType.IconName); HasMany<LocalizedEntity>(activityType => activityType.Descriptions) .WithTableName("[7de_LocalizedEventTypes]") .Component(description => { description.References<Language>(desc => desc.Language) .CanNotBeNull(); description.Map(desc => desc.Localization) .CanNotBeNull(); }); } } |

