Contents tagged with Unity

  • 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.

  • 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 :)