Dev Blog - Johan Danforth

I'm Johan Danforth and this is my dev blog - a mix of .NET, ASP.NET, Rest, Azure and some other random coding stuff.

  • Integration Testing WCF Services with Unity

    I've been blogging a few times now about using Unity with WCF, but how do you integration test your service in an easy way without? The way I (and many others) do integration tests for a WCF service is by setting up my own service host and starting the service from test init:

        [TestClass]

        public class ServiceIntegrationTest

        {

            private static ServiceHost serviceHost;

     

            [ClassInitialize]

            public static void MyClassInitialize(TestContext testContext)

            {

                serviceHost = new ServiceHost(typeof(Service1), new [] { new Uri("http://127.0.0.1:8001/") });

                serviceHost.AddServiceEndpoint(typeof(IService1), new BasicHttpBinding(), "Service1");

                serviceHost.Open();

            }

     

            [ClassCleanup]

            public static void MyClassCleanup()

            {

                serviceHost.Close();

            }

     

            [TestMethod]

            public void Should_get_data()

            {

                var ep = new EndpointAddress("http://127.0.0.1:8001/Service1");

                var proxy = ChannelFactory<IService1>.CreateChannel(new BasicHttpBinding(), ep);

                var data = proxy.GetData(1);

                Assert.IsTrue(data == "You entered: 1", "Got wrong data back, got - '" + data + "'");

            }

        }

    By doing it this way I don't have to make sure Cassini is started up before the test or having to deploy the service to a local IIS. There is no need for web.config or app.config files and I don't have to add any service reference. This way of doing integration testing of services is described by many others, and it should work quite well on a TFS build server or similar.

    Integration Testing WCF Service with Unity

    A few blog posts away I wrote about using Unity with WCF, but how do you integration test a setup like that? Remeber that if you have created your own ServiceHostFactory, you specify the factory to use in the .svc markup using the Factory attribute this:

    <%@ ServiceHost Language="C#" Debug="true" Factory="IRM.Patterns.UnityService.UnityServiceHostFactory" Service="WcfService3.Service1" CodeBehind="Service1.svc.cs" %>

    The "problem" here is that the factory doesn't have any decent public methods to let you create the service host from a given service type. True, there is a CreateServiceHost method which accepts a string representation of the type, but that means your service host factory has to have a reference to the type in question. The way I went around that small issue is by creating a small "harness" around the factory, with a public method which accepts a Type:

        public class UnityServiceHostFactoryHarness : UnityServiceHostFactory

        {

            public ServiceHost CreateServiceHost(Type serviceType, string baseAddress)

            {

                return CreateServiceHost(serviceType, new[]

                                                          {

                                                              new Uri(baseAddress)

                                                          });

            }

        }

    A small change to the test-initialize method makes use of this test-harness:

            [ClassInitialize]

            public static void MyClassInitialize(TestContext testContext)

            {

                var serviceHostFactoryHarness = new UnityServiceHostFactoryHarness();

     

                serviceHost = serviceHostFactoryHarness.CreateServiceHost(typeof(Service1), "http://127.0.0.1:8001/");

                serviceHost.AddServiceEndpoint(typeof(IService1), new BasicHttpBinding(), "Service1");

                serviceHost.Open();

            }

    Now we're running service integration tests and we have the Unity container loaded as well. I'm sure there are other, smarter and for me uknown ways of achieving the same, but it works for me :) If you want sample code for the UnityServiceHostFactory, please let me know, but know that my code is based on the this sample.

  • ISO Recorder

    This free (Alex accepts PayPal donations) ISO Burner/recorder works pretty well on Vista and got both 32 and 64-bit versions. Quote from his site:

    ISO Recorder is a tool (power toy) ...snip...  to burn CD and DVD images (DVD support is only available on Windows Vista), copy disks, make images of the existing data CDs and DVDs and create ISO images from a content of a disk folder.

    Insert blank DVD, right click on an .iso file and select "open with ISO Recorder" and a few clicks later you got your DVD burned. Just the way I like it.

  • NHibernate and WCF is Not a Perfect Match

    From the last days of playing around with and learning NHibernate it's quite clear to me that NHibernate is not a perfect match for a WCF solution. I'm perfectly aware of the fact that I'm still a total NH newbie, so please correct me or help me out if you can.

    From the moment I heard of Hibernate years ago I thought it was best made for stateful solutions and not web apps or web services, and from what I can see that is still the case. I like many of the things I see in NH, especially the way you can map existing and bad looking databases to better looking domain entities, and the work on NHibernate Fluent looks promising.

    You have to understand how lazy loading does (not) work with web services and serializing problems you may run into. But I think the biggest problem lies in the session management of NHibernate and where to open and close your NHibernate session. I won't even go into the different options proposed by hundreds of bloggers, just Google it. The thing is I don't want to be dependant on more 3rd party or open source components than necessary - it can easily get out of control.

    I still want to use NHibernate for our WCF project because I do think can help us map the old, existing database we have to work with to decent domain entities, but I'm afraid we will run into weird problems later on. This approach seems to be one of the best so far, but I need to test it out some more and I'm not sure it will handle lazy loaded/HasMany data. Quite a few projects have run into problems with the session being closed before the serialization of lazy loaded objects happens :/

    We may have to use EF instead.

  • WCF, Unity and NHibernate - First Findings

    This blog post is to continue on the one I wrote a few days ago about a new architecture for a WCF project we're trying out.

    My colleague Tomas and I sat down the whole day yesterday and dug into the topic and came out with a first rough code architecture that seems to work. Both of us knows WCF pretty well, but we're new to Unity and NHibernate so this baby has to be tested thoroughly :)

    First, thanks to Ray Henry, who wrote a couple of nice posts about how to use Unity with WCF. That information was superb. Basically we're using a custom Service Host Factory which we point at from the .svc markup file:

    <%@ ServiceHost Language="C#" Debug="true" Service="WcfUnity.TestService" 
    CodeBehind="TestService.svc.cs" Factory="WcfUnity.UnityService.UnityServiceHostFactory" %>

    The UnityServiceHostFactory is where we currently registers the types that is to be injected into our code. Right now we're doing it in code, and we're only working with 2 classes; the NHibernate Repository and the NHibernate Session Manager (which is a singleton):

            protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)

            {

                var unity = new UnityContainer()

                .RegisterType<IRepository, NHibernateRepository>()

                .RegisterType<INHibernateSessionManager, NHibernateSessionManager>(new ContainerControlledLifetimeManager());

     

                var host = new UnityServiceHost(serviceType, baseAddresses)

                               {

                                   Container = unity

                               };

     

                return host;

            }

    The Session Manager is responsible for setting up the NHibernate Session Factory which is expensive and you only want to do that once. In short - the factory creates a new WCF service host which creates a service behavior which is called each time before a requested service class is instantiated. To be able to resolve and inject our registered classes, the behavior uses a specific instance provider which does Resolve as part of its GetInstance() method. It's all described in detail by Ray in his post, so go check it out. I've not seen a better example of Unity + WCF out there yet and from what I can see in our, so far limited, testing it works well.

    When that plumbing is done (some 4 small classes, that's all), we got a very clean service implementation class with the IRepository injected into it:

        public class TestService : ITestService

        {

            private readonly IRepository _repository;

     

            public TestService(IRepository repository)

            {

                _repository = repository;

            }

     

            // ITestService members goes here...

     

        }

     

    You don't see any trace if a container, just the way it should be. Currently we're looking at our Repository interface and a decent syntax for a Unit Of Work. I'm fond of the lambda style of coding, and I'm playing something like this now:

                var response = new GetPersonResponse();

                _repository.UnitOfWork(() =>

                   {

                       var person = _repository.Find<Person>(request.Id);

                       ret.Person = person;

                   });

                return response;

    Or for a transaction:

                var response = new AddPersonResponse();

                _repository.TransactionalUnitOfWork(() =>

                    {

                        _repository.Save(request.Person);

                        response.Person = _repository.Find<Person>(request.Person.Id);

                    });

                return response;

    The TransactionalUnitOfWork method would do things like:

            public void TransactionalUnitOfWork(Action action)

            {

                _session = sessionManager.GetSession();

                var transaction = _session.BeginTransaction();

                try

                {

                    action();

                    transaction.Commit();

                }

                catch (Exception)

                {

     

                    transaction.Rollback();

                    throw;

                }

                finally

                {

                    transaction.Dispose();

                    _session.Close();

                }

            }

    The "problem" is that the UoW shouldn't go into the repository implementation, it's wrong but I'm only trying things out here. I might as well wrap the opening and closing of a NH Session and transaction within an IDisposable and call it my UoW as many others have done before me, but I kind of like this. Have to think about not letting things that should stay inside the repository "leak" out... At this moment we're only playing around with things :)

    We also need to encapsulate and inject business rules in a good way as we will host the services at more than one customer with different rules. MEF could be an option actually... more on that later :)

  • Please Feedback! Unity, nHibernate, Fluent, Linq... Trying New Architecture Combinations

    We're thinking about a new architecture for a set of pretty large WCF (and perhaps also REST) services that's going to be developed during the next year and perhaps you dear reader would like to comment!

    The services themselves are pretty straight forward, we're going to serve data from a huge SQL Server database which unfortunately is old and lacks relationship/fk/pk between most tables. Nothing we can do about that I'm afraid but we thought that nHibernate could be a good way to map data to domain objects. Some of the services will need to handle more complex business rules, but no heavy computing or long running stuff (not atm anyway).

    What more can I say... everything is going to be running on .NET 3.5, and we have a pretty good view of the business domain, we're currently modelling the information/domain together with the customer and we will probably be developing the whole thing in a DDD-ish way, using unit and integration tests, IoC...

    So, currently we're thinking of WCF/REST for the service layer, Unity as container and building something around nHibernate for the Repository (looking at the IRepository implementation in Fluent). We're new to nHibernate but have been looking at nHibernate.Linq which looks really nice, and I think we'll use the Fluent API and map the classes in code instead of using XML configuration (which I'm allergic against). Just have to figure out a good way to make it all fit together, especially to get a decent UnitOfWork to work with the nHibernate session and the repository. I'll see what I come up with and post it here.

    Ideas? Please comment or send me an email of you like.

  • WPF Learnings - Drawing on Multiple Monitors

    Writespace Some time ago I wrote a fullscreen editing environment add-in for Word to learn some WPF and some Office Ribbon stuff. The editor is called Writespace and is now available om Codeplex as open source.

    Scott Hanselman was kind enough to take a few minutes and review the first draft of the editor and told me I should support multiple monitors and that I could look at BabySmash code to see how he did it. Said and done, I downloaded the BabySmash code, dug into the multi-monitor stuff and found out it's not that strange.

    Writespace is a fullscreen editor, and when the user press CTRL+M I want to move the whole thing over to the next available monitor. First you may want to do some sanity check that you got more than one monitor available. This is easy enough with something like this:

    if (SystemInformation.MonitorCount < 2)

    {

        ...only one monitor available...

    }

     

    The different screens are available via the Screen.AllScreens[] array so once I've picked a screen to draw on I send it as a paramter to a CreateEditor() method:

    private static void CreateEditor(Screen screen)

    {

        var editor = new TextEditorWindow

                        {

                            WindowStartupLocation = WindowStartupLocation.Manual,

                            Left = screen.WorkingArea.Left,

                            Top = screen.WorkingArea.Top,

                            Width = screen.WorkingArea.Width,

                            Height = screen.WorkingArea.Height

                        };

     

        //setting up other stuff, like events and things here...

     

        editor.Show();

        editor.WindowState = WindowState.Maximized; //do this after Show() or won't draw on secondary screens

        editor.Focus();

    }

    The setting of WindowState to Maximized after Show() is a trick/workaround for something that seems to be a bug or something I don't grok about WPF in full screen and multiple monitors. The editor window itself has WindowStyle="None" ResizeMode="NoResize" set.

    Hope this helps someone.

  • Big Problems with iTunes and App Store

    itunesappstoreApple currently got what seems to be huge probs with iTunes and the iPhone App Store. People all over the world cannot log into iTunes App Store to buy and upgrade programs because of connection timeouts. Some people are taking it with a smile, I guess they're used to it:

    It's only 3:30AM in Cupertino. You don't expect an online store to be open in the middle of the night, do you?

    I wrote yesterday about my gripes with iTunes, and this sure doesn't make things better I can tell you. One would think that Apple had the App Store system spread out the world for concurrency and minimize problems like this, but apparently not.

  • iTunes and iPhone...

    Why is iTunes one of the most widespread, annoying, unresponsive but still CPU-munching program out there? Probably because you cannot sync your iPhone without installing it... It's amazingly bad and Apple has to do something about it.

    There... feels much better now, but I'm definitely getting closer and closer to that jailbreak decision.

  • Windows Live ID Becomes an OpenID Provider

    openid According to this blog post on the Windows Live Dev blog:

    Beginning today, Windows Live ID is publicly committing to support the OpenID digital identity framework with the announcement of the public availability of a Community Technology Preview (CTP) of the Windows Live ID OpenID Provider.

    You will soon be able to use your Windows Live ID account to sign in to any OpenID Web site!

    The Windows Live ID OpenID Provider (OP) enables anyone with a Windows Live ID account to set up an OpenID alias and to use that alias for identification at an increasing number of OpenID 2.0 relying party sites-for example: Plaxo, Pibb, StackOverflow.com and Wikispaces.

    I think it's just brilliant and a move in the right direction.

  • Visual Studio 2010 and .NET Framework 4.0 CTP Direct Links

     Visual Studio 2010 and .NET Framework 4.0 CTPVisual Studio 2010 and .NET Framework 4.0 CTP

    Want to download and play with the VS 2010 bits? You can read about and download it from MSDN Downloads, or install a pretty good Download Manager (open source, GNU GPL, quite good IMHO) and cut/paste the direct links below.

    http://download.microsoft.com/download/d/c/5/dc51bdda-8925-4aef-b6d9-4d07e4dc6737/VisualStudio2010CTP_11PartsTotal.part11.rar
    http://download.microsoft.com/download/d/c/5/dc51bdda-8925-4aef-b6d9-4d07e4dc6737/VisualStudio2010CTP_11PartsTotal.part10.rar
    http://download.microsoft.com/download/d/c/5/dc51bdda-8925-4aef-b6d9-4d07e4dc6737/VisualStudio2010CTP_11PartsTotal.part09.rar
    http://download.microsoft.com/download/d/c/5/dc51bdda-8925-4aef-b6d9-4d07e4dc6737/VisualStudio2010CTP_11PartsTotal.part08.rar
    http://download.microsoft.com/download/d/c/5/dc51bdda-8925-4aef-b6d9-4d07e4dc6737/VisualStudio2010CTP_11PartsTotal.part07.rar
    http://download.microsoft.com/download/d/c/5/dc51bdda-8925-4aef-b6d9-4d07e4dc6737/VisualStudio2010CTP_11PartsTotal.part06.rar
    http://download.microsoft.com/download/d/c/5/dc51bdda-8925-4aef-b6d9-4d07e4dc6737/VisualStudio2010CTP_11PartsTotal.part05.rar
    http://download.microsoft.com/download/d/c/5/dc51bdda-8925-4aef-b6d9-4d07e4dc6737/VisualStudio2010CTP_11PartsTotal.part04.rar
    http://download.microsoft.com/download/d/c/5/dc51bdda-8925-4aef-b6d9-4d07e4dc6737/VisualStudio2010CTP_11PartsTotal.part03.rar
    http://download.microsoft.com/download/d/c/5/dc51bdda-8925-4aef-b6d9-4d07e4dc6737/VisualStudio2010CTP_11PartsTotal.part02.rar
    http://download.microsoft.com/download/d/c/5/dc51bdda-8925-4aef-b6d9-4d07e4dc6737/VisualStudio2010CTP_11PartsTotal.part01.exe

    NOTE! There are some system requirements that you should be aware:

    • Supported Operating Systems: Windows Server 2003; Windows Server 2008; Windows Vista; Windows XP
    • Minimum 75 GB available HDD space
    • The host computer must have a minimum of 2 GB RAM, with 1 GB allocated to the host operating system and 1 GB allocated to the VPC.
    • We recommend that the host computer CPU be at least a Core Duo 2 GHz processor.
    • Service Pack 1 of Microsoft Virtual PC 2007 is required to access the VPC.

    You also need to download and install Virtual PC 2007 and then upgrade to Virtual PC 2007 Service Pack 1.