in

 

Jimmy Bogard

Assistant to the assistant to the regional manager

July 2008 - Posts

  • Trusted Subsystem, WCF and IIS 5 - revisited

    In my last post, I tried to get the following scenario to work:

    One thing I didn't add was that I'm running IIS in Windows XP, in IIS 5.  In this article on CodePlex, which I originally modeled my solution after and a couple of folks pointed out, it recommends setting both the ASP.NET identity (outside the Trusted Zone) and the App Pool identity to the Service account identity.

    Now, in my case, I don't care about who calls my service, nor do I want any requirement on their side to provide any transport security.  The article also recommends this, but I don't need it.

    The real problem came from me running in IIS 5.  In IIS 5, the aspnet_wp process runs as MACHINE\ASPNET, which examining WindowsIdentity.GetCurrent() confirmed.  Even though I set the identity in IIS to use the service account as anonymous user, WCF by default uses the process identity, not any other identity.  WCF has no knowledge of the host environment, by default, so it doesn't know it's hosted in ASP.NET or IIS normally.

    To do a Trusted Subsystem model under IIS 5, I had to make the following changes:

    • Set the anonymous account to the service account, turn off any other security (like Integrated Windows Security)
    • Turn on impersonation in the web.config (<identity impersonate="true" />)
    • Turn on ASP.NET compatibility for the service hosting environment and each individual service

    The last part is critical, and detailed in this MSDN article.  I've had to do that before, when designing JSON services for an AJAX application, where the services needed access to HttpContext.Session.

    Once ASP.NET compatibility is turned on, WCF requests now go through the ASP.NET pipeline, which means the normal ASP.NET impersonation model.  From the article:

    WCF services run using the current identity of the ASP.NET impersonated thread, which may be different than the IIS process identity if ASP.NET impersonation has been enabled for the application.

    With the full ASP.NET impersonation set up, and the correct identity set up in IIS, WCF could now take the identity of the ASP.NET impersonated thread.  Even though Thread.CurrentPrincipal reflected the service identity, WCF won't use it unless I set up the compatibility mode.

    Of course, if I had been developing in a Workstation 2008 machine, or something with IIS 6 or 7, this wouldn't be a problem.  Setting the App Pool identity is the process identity.  In IIS 5, the identity is configured elsewhere.  In any case, it's all working now locally.  I guess this means it's finally time to upgrade to Workstation 2008.

    Thanks to everyone for all the pointers!

    Posted Jul 31 2008, 08:26 PM by bogardj with 4 comment(s)
    Filed under:
  • Trusted Subsystem, WCF and IIS

    I've just about pulled my hair out on this one.  This used to be very easy with ASMX:

    Basically, I have IIS running as a trusted user, "Service".  I want WCF to run as this user for connecting to databases, etc.  I don't care who's calling me, I'm in an intranet environment, and this service is open to the world.  Unfortunately, all I can ever get is "user not associated with a trusted connection", no matter what I do.  I suspect it's due to a network hop issue, or something similar.  I can get it to work by flowing identity down, but I don't want to do that, it's not Trusted Subsystem.

    I've spent about a day on two separate occasions trying to get this to work, but all examples seem to force me to set the service account on the ASP.NET side.  But I don't want to force clients to do any kind of security, that defeats the purpose.

    The quickest way to Trusted Subsystem now is to use SQL Server authentication.  With ASMX, I used ASP.NET configuration, along with IIS security configuration to set the identity, and it worked just fine.  WCF works outside the ASP.NET stack, so I don't have that luxury.  Security in WCF is tough, kids, don't let anyone tell you any different.

    Boo.

    Posted Jul 30 2008, 10:43 PM by bogardj with 6 comment(s)
    Filed under:
  • Integrating StructureMap with WCF

    When developing with an IoC container like StructureMap, eventually some place in your code you will need to call the registry to instantiate your classes with their dependencies.  With StructureMap, this means a call to ObjectFactory.GetInstance.  Ideally, we'd like to limit the number of places the registry is called, so that we don't have a lot of StructureMap concerns sprinkled throughout our application.

    Suppose we have the following WCF service:

    public class CustomerSearchService : ICustomerSearchService
    {
        private readonly ICustomerRepository _customerRepository;
        private readonly ICustomerSummaryMapper _customerSummaryMapper;
    
        public CustomerSearchService(ICustomerRepository customerRepository, ICustomerSummaryMapper customerSummaryMapper)
        {
            _customerRepository = customerRepository;
            _customerSummaryMapper = customerSummaryMapper;
        }
    
        public CustomerSearchResult FindCustomerByName(string fullName)
        {
            Customer customer = _customerRepository.FindCustomerByName(fullName);
    
            if (customer == null)
            {
                return new CustomerSearchResult
                           {
                               IsSuccessful = false,
                               FailureReasons = new[] {"Customer not found."}
                           };
            }
    
            CustomerSummary summary = _customerSummaryMapper.MapFrom(customer);
    
            return  new CustomerSearchResult {IsSuccessful = true, Result = summary};
        }
    }
    

    Nothing too exciting, just a search service that returns customer summary information from a name search.  Now, if we just try to use this service as is, we get a fun exception:

    The service type provided could not be loaded as a service because it does not have a default (parameter-less) constructor. To fix the problem, add a default constructor to the type, or pass an instance of the type to the host.

    That makes sense, as WCF is in charge of instantiating my service class (CustomerSearchService), but it only knows how to call a no-args constructor.  For a quick fix, we can add this constructor:

    public CustomerSearchService()
        : this(ObjectFactory.GetInstance<ICustomerRepository>(), 
            ObjectFactory.GetInstance<ICustomerSummaryMapper>())
    {
    }
    

    Each of our WCF services would need to the same thing, have a bunch of ObjectFactory calls to set up the dependencies appropriately.  But we can find a better way, and have all of our services wired up automatically, with only one call to StructureMap in the entire application.  To do this, we'll need to plug in to a few WCF extension points to make it happen.

    A custom instance provider

    WCF provides an interface just for this purpose, IInstanceProvider, that allows us to create custom instantiation behavior.  This interface has basically two methods:

    • CreateInstance - needs to return the right service
    • ReleaseInstance - if we have some custom cleanup to do

    Just creating the IInstanceProvider isn't enough, we'll have to tell WCF to use our instance provider, instead of its own default instance provider.  This requires a custom endpoint behavior.  We can't configure the instance provider directly, through configuration or other means.  Instead, we'll use a custom service behavior through the IServiceBehavior interface.  Here's the implementation of our custom service behavior:

    public class StructureMapServiceBehavior : IServiceBehavior
    {
        public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
        {
            foreach (ChannelDispatcherBase cdb in serviceHostBase.ChannelDispatchers)
            {
                ChannelDispatcher cd = cdb as ChannelDispatcher;
                if (cd != null)
                {
                    foreach (EndpointDispatcher ed in cd.Endpoints)
                    {
                        ed.DispatchRuntime.InstanceProvider = 
                            new StructureMapInstanceProvider(serviceDescription.ServiceType);
                    }
                }
            }
        }
    
        public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters)
        {
        }
    
        public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
        {
        }
    }
    

    For all of the endpoints in all of the channels, we need to give WCF our custom instance provider.  Also, since StructureMap needs to know what type to create, we have to pass that information along to our instance provider.  This comes from the ServiceDescription passed in above.

    With our service behavior done, let's create the actual instance provider, which will call StructureMap:

    public class StructureMapInstanceProvider : IInstanceProvider
    {
        private readonly Type _serviceType;
    
        public StructureMapInstanceProvider(Type serviceType)
        {
            _serviceType = serviceType;
        }
    
        public object GetInstance(InstanceContext instanceContext)
        {
            return GetInstance(instanceContext, null);
        }
    
        public object GetInstance(InstanceContext instanceContext, Message message)
        {
            return ObjectFactory.GetInstance(_serviceType);
        }
    
        public void ReleaseInstance(InstanceContext instanceContext, object instance)
        {
        }
    }
    

    Pretty straightforward, we just capture the service type (passed in from our service behavior earlier), then use ObjectFactory to create an instance of that service when asked.  There's no information on the InstanceContext about the service type, or we could have just used it instead.

    Now that we have our IInstanceProvider and IServiceBehavior, it's time to hook up this new service behavior to the rest of WCF.  We have a few choices:

    • Attributes
    • Custom service host
    • Configuration

    With attributes, we'd decorate all of our services with something like [StructureMapServiceBehavior] or something similar, so that WCF would know to attach our IServiceBehavior to the ServiceDescription behaviors.  Attributes are okay, but again, we'd have to put something on all of our services.  Since the whole point of this exercise was to reduce the footprint, let's go the custom service host route.

    As for configuration, I can't stand XML, so let's just pretend that one doesn't exist.

    A custom service host

    By going the custom ServiceHost route, we'll just need to plug in to the right event to add our custom service behavior to the mix.  Here's what we wind up creating:

    public class StructureMapServiceHost : ServiceHost
    {
        public StructureMapServiceHost()
        {
        }
    
        public StructureMapServiceHost(Type serviceType, params Uri[] baseAddresses)
            : base(serviceType, baseAddresses)
        {
        }
    
        protected override void OnOpening()
        {
            Description.Behaviors.Add(new StructureMapServiceBehavior());
            base.OnOpening();
        }
    }
    

    Nothing too exciting, we just add our custom service behavior to the ServiceDescription Behaviors collection, right before the service host is opened in the OnOpening method.

    Next, to plug in our custom service host, we'll need a custom service host factory:

    public class StructureMapServiceHostFactory : ServiceHostFactory
    {
        public StructureMapServiceHostFactory()
        {
            StructureMapConfiguration
                .ScanAssemblies()
                .IncludeTheCallingAssembly()
                .With<DefaultConventionScanner>();
        }
    
        protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
        {
            return new StructureMapServiceHost(serviceType, baseAddresses);
        }
    }
    

    The overridden method makes sense, override the CreateServiceHost to...create our custom service host.  However, there's quite a bit going on in the constructor.

    At this point, it will start to matter how you'd like StructureMap to be configured:

    • Attributes
    • XML config
    • Code

    I'm liking the code way, as we don't have to have crazy XML or a bunch of attributes everywhere.  Which way you configure is up to you, but if you go the code route, you'll need to put the StructureMap configuration in the constructor here.

    Finally, we'll need to configure our WCF service to use this service host factory.  I'm using IIS to host, so I'll just need to change my .svc file:

    <%@ ServiceHost Language="C#" Debug="true" 
        Service="SMExample.Wcf.CustomerSearchService" 
        Factory="SMExample.Wcf.StructureMapServiceHostFactory" %>
    

    Other hosting solutions will use different ways of using the custom service host factory.

    Recap

    We wanted to use StructureMap with WCF, but this initially presented us with some problems.  WCF requires a no-args constructor, which means we'll have to use a lot of ObjectFactory.GetInstance calls on every service implementation.

    Instead, we can use WCF extension points to use StructureMap to create the service for us, without needing that messy constructor.  We created two extensions:

    • IInstanceProvider
    • IServiceBehavior

    Once we had our custom instance provider and service behavior, we needed to decide how our custom service behavior would get attached to our service.  We chose the custom service host route, which meant two more custom WCF implementations:

    • ServiceHost
    • ServiceHostFactory

    The ServiceHostFactory implementation forced us to decide how our dependencies should be configured in StructureMap, and we went the code route.  Finally, we configured our service host in IIS to use the right service host factory.

    With all this in place, none of our service classes nor their implementations need to know anything about StructureMap, allowing their design to grow and change outside of WCF construction concerns.  We also reduced the footprint of StructureMap in our application, where we now had exactly one call to the StructureMap infrastructure, ObjectFactory.GetInstance.  With this one place StructureMap is used, it will be easier to swap out IoC container implementations (just kidding, Jeremy).

  • Arrange Act Assert and BDD specifications

    With Rhino Mocks 3.5 just around the corner, I've started using it to create much more readable tests.  One of the things that always bothered me with Expect.Call, constraints and the like was that it mixed in the Arrange with Assert.  For those that haven't heard of AAA, it's a pattern for authoring unit tests:

    • Arrange - set up the unit under test
    • Act - exercise the unit under test, capturing any resulting state
    • Assert - verify the behavior through assertions

    As I moved towards BDD context/specification style tests, working with Rhino Mocks didn't fit the picture very well.  But with the new AAA syntax of Rhino Mocks 3.5, I can very cleanly separate out the behavior I want to observe from the mechanics of setting up the test.

    Here's a normal unit test, as I would have written it about a year ago:

    [Fact]
    public void Should_send_email_when_order_is_over_200()
    {
        MockRepository repo = new MockRepository();
    
        //Arrange
        ISmtpClient mockClient = repo.DynamicMock<ISmtpClient>();
        IOrderSpec stubSpec = repo.DynamicMock<IOrderSpec>();
        MailMessage actual = null;
    
        Order order = new Order();
        order.Total = 201.0m;
    
        using (repo.Record())
        {
            mockClient.Send(null);
    
            // Also assert?
            LastCall
                .IgnoreArguments()
                .Do(new Action<MailMessage>(message => actual = message));
    
            SetupResult
                .For(stubSpec.IsMatch(order))
                .Return(true);
        }
    
        OrderProcessor pr = new OrderProcessor(mockClient, stubSpec);
    
        // Act
        pr.PlaceOrder(order);
    
        // Assert
        actual.ShouldNotBeNull();
        actual.To.Count.ShouldEqual(1);
        actual.To[0].Address.ShouldEqual("salesdude@email.com");
    
        repo.VerifyAll();
    }
    

    It's a really long test, but the basic idea is that an email needs to be sent out to the sales guy when big orders get placed.  The sales guy wanted to follow up immediately, to try and sell more (we think).  I see many issues with this test:

    • It's frickin' huge
    • I can't tell what the point of it is at first glance
    • It's really hard to tell what's being tested

    Moving towards the context/specification style, but still with Rhino Mocks improved things somewhat, but it's still quite awkward:

    public class When_placing_a_large_order 
        : ContextSpecification
    {
        private MockRepository _repo;
        private OrderProcessor _orderProcessor;
        private Order _order;
        private MailMessage _actual;
    
        protected override void EstablishContext()
        {
            _repo = new MockRepository();
    
            ISmtpClient mockClient = _repo.DynamicMock<ISmtpClient>();
            IOrderSpec stubSpec = _repo.DynamicMock<IOrderSpec>();
            _actual = null;
    
            _order = new Order();
            _order.Total = 201.0m;
    
            using (_repo.Record())
            {
                mockClient.Send(null);
    
                // Also assert?
                LastCall
                    .IgnoreArguments()
                    .Do(new Action<MailMessage>(message => _actual = message));
    
                SetupResult
                    .For(stubSpec.IsMatch(_order))
                    .Return(true);
            }
    
            _orderProcessor = new OrderProcessor(mockClient, stubSpec);
        }
    
        protected override void Because()
        {
            _orderProcessor.PlaceOrder(_order);
        }
    
        [Test]
        public void Should_send_the_email_out()
        {
            _actual.ShouldNotBeNull();
        }
    
        [Test]
        public void Email_sent_should_be_addressed_to_the_sales_guy()
        {
            _actual.To.Count.ShouldEqual(1);
            _actual.To[0].Address.ShouldEqual("salesdude@email.com");
        }
    
        [Test]
        public void Should_verify_all_expectations()
        {
            _repo.VerifyAll();
        }
    }
    

    Again, I have to do some strange things to capture the output, and the record/replay model doesn't jive well with BDD-style specifications.  I always had this one observation that said, "Should verify all expectations".  Not very interesting, and not descriptive of the behavior I want to observe.  It doesn't describe any behavior, just some cleanup assertion for the MockRepository.

    Finally, let's see how the AAA syntax of Rhino Mocks 3.5 clears things up:

    public class When_placing_a_large_order 
        : ContextSpecification
    {
        private OrderProcessor _orderProcessor;
        private Order _order;
        private ISmtpClient _mockClient;
    
        protected override void EstablishContext()
        {
            _mockClient = Dependency<ISmtpClient>();
            IOrderSpec stubSpec = Stub<IOrderSpec>();
    
            _order = new Order();
            _order.Total = 201.0m;
    
            stubSpec.Stub(x => x.IsMatch(_order)).Return(true);
    
            _orderProcessor = new OrderProcessor(_mockClient, stubSpec);
        }
    
        protected override void Because()
        {
            _orderProcessor.PlaceOrder(_order);
        }
    
        [Test]
        public void Should_send_the_email_to_the_sales_guy()
        {
            _mockClient.Expect(x => x.Send(Arg<MailMessage>.Matches(msg => msg.To[0].Address == "salesdude@email.com")));
        }
    }
    

    That's a lot smaller!  I clearly separate the Arrange (EstablishContext) from Act (Because) and the Assert, which is my actual observation.  To stub the indirect input of the IOrderSpec, I can use the Stub extension method provided by Rhino Mocks 3.5.

    But the best aspect of the new AAA syntax is that I can finally create readable specifications that use Rhino Mocks.  Before, all of the noise of the Record/Replay and the MockRepository obscured the intention of the specification.  I had to rely on test spies earlier to capture the output of the ISmtpClient.Send call, as the old constraint model would have mixed in the Assert with the Arrange (i.e., I would have to put the constraints in the record section.  Not pretty.)

    I've found that without the distractions of the old Rhino Mocks syntax, I can better focus on the behavior I'm trying to observe.  It's now just one line to set up indirect inputs with stubs, and one line to verify interactions and indirect outputs.

  • Showing some MVC support

    Joey was kind enough to create a shirt to support MVC:

    CafePress shirt

    Love it.  Alternatively, if you want to show your WebForms support, write to the Long Live WebForms guy.

  • Expressions and Lambdas

    Some conversation on a recent post on Chad's blog brought up the confusion between Lambdas and Expressions.  A while back, I went into the various ways to create delegates throughout the different versions of C#.  Although I touched on it briefly, the slight variations in the different lambda types can lead to some unexpected compilation errors.

    C# 3.0 introduced two types of lambdas: Expression Lambdas and Statement Lambdas.  The difference is easy to spot, here are two identically functioning lambdas:

    public void LambdaExpressionsAndStatements()
    {
        var books = GetBooks();
    
        var exprBooks = books.Find(book => book.Author.Contains("Fowler"));
    
        var stmtBooks = books.Find(book => { return book.Author.Contains("Fowler"); });
    }
    

    See the difference?  The second lambda has brackets.  These brackets are a statement block, and can contain any old C# code.  The statement lambda is really just a shorter version of a C# 2.0 anonymous method.

    The first version is a different type of lambda: the expression lambda.  So why do both compile?  The Find method's signature is:

    public T Find(Predicate<T> match)

    Predicate<T> is a delegate type, so how does the "book.Author.Contains" part of the first lambda get converted to a delegate?

    It turns out that the C# compiler is really smart.  Smart enough to see an expression that returns a boolean, which matches the signature of the Predicate delegate.  At compile time, it creates an anonymous delegate from the expression, as confirmed by Reflector.  So we couldn't do something like this:

    var exprBooks = books.Find(book => book.Author.Split(' '));

    We get the compiler error:

    Cannot convert lambda expression to delegate type 'System.Predicate<Samples.Book>' because some of the return types in the block are not implicitly convertible to the delegate return type

    Basically, that the return type of the Split call (string[]) isn't boolean, so it doesn't compile.

    Expressions

    Expressions are a fundamental addition to C# that allows LINQ to work its magic.  Expressions at compile-time are converted to expression trees, which is really a large object made up of things like equals statements, variables, etc.  It's as if you decomposed C# statements into their fundamental building blocks, and represented these building blocks as classes and objects.

    The interesting thing about expressions is that they can be converted to lambdas, and therefore executable code.  Lambda statements however, don't jive with expressions.  Since lambda statements contain actual blocks of code, rather than an expression that represents a block of code, the compiler can't convert all of those potential lines of code of a statement block into a real-deal expression.  It's why you can't do this in a LINQ query expression:

    var linqBooks = from book in books
                    where { return books.Author.Contains("Fowler"); }
                    select book;
    

    I get a nasty compile error:

    Invalid expression term '{'

    I tried to use a lambda statement (the bracket business) where a lambda expression was required.  A LINQ query expression is compiled into an expression tree, mixed in with the extension method calls to the LINQ query extensions (Where, Select, Union etc.)  Here's another way to write the above LINQ query expression, using LINQ query extensions instead:

    var linqStmtBooks = books.Where(book => { return book.Author.Contains("Fowler"); });

    This looks exactly like our original Find example above, but this time I'm using the LINQ query extension method, instead of the List<T>.Find method.  But LINQ query expressions (the SQL-like from..where..select) requires expressions, not statements.

    Why do I care?

    Well, 99.999% of the time, you won't.  Most folks won't develop any APIs that use Expression<T> (the actual type behind the expression trees).  Unless you're someone like Oren or Jeremy of course.

    But if you happen to use an API that works with Expression<T> instead of Func (delegates), you'll need to care. For example, LINQ to SQL, LINQ to NHibernate and Entity Framework all deal with Expressions, not Funcs.  So you'll need to use the lambda expressions instead of the lambda statements.  No brackets allowed!

    So if you're dealing with LINQ query expressions (the "from..where..select" business), you'll have to go out of your way to do LINQ query statements with brackets.  But using other APIs, you'll get a strange compile error.  If you see this compile error, just use an expression instead of a statement, and you'll be set.

    Posted Jul 18 2008, 10:59 PM by bogardj with 4 comment(s)
    Filed under:
  • Separation of Concerns by example: Part 5

    In our last example, disaster finally struck our quaint little application.  A strange defect showed up, which would be almost impossible to reproduce back on our developer machine.  But because we've broken out our dependencies, our CustomerFinder became easier to test.  When it became easier, actually possible to test, we were able to reproduce the circumstances of the bug.

    With the dependencies broken out, we were able to push in fake versions through the constructor.  With our behavioral specifications in place, guarding us against this bug in the future, we can have complete confidence that this bug is fixed now and forever.

    Other parts in this series include:

    There's still one last bothersome piece of our application, the construction of the CustomerFinder.  We split out the dependencies quite nicely, and told the clients of the CustomerFinder exactly what is needed for the class to function:

    public class CustomerFinder
    {
        private readonly ICustomerRepository _customerRepository;
        private readonly ICustomCache _customCache;
    
        public CustomerFinder(ICustomerRepository customerRepository, ICustomCache customCache)
        {
            _customerRepository = customerRepository;
            _customCache = customCache;
        }
    

    However, now it's on the burden of the client to find the right implementations of the dependencies to plug in.  The problem is, clients often don't care what gets plugged in, they too only care that they get a CustomerFinder.  Sure, some users of this class might want some different implementation, but by and large, we'd like to encapsulate selection of dependencies away from CustomerFinder clients.

    We have quite a few options for this complex construction:

    • An overloaded constructor that picks the right instances
    • A static creation method (CustomerFinder.CreateInstance())
    • A separate factory class
    • Dependency injection with an Inversion of Control container

    All of these are valid options with their own advantages and disadvantages.  However, the last option allows some interesting benefits, such as changing implementations out from configuration at runtime.  Suppose we want to see how our application runs when the database is slow?  Or a certain external service is down, slow, or not responding?

    Preparing for StructureMap

    Here's the offending code we'd like to fix:

    public class CustomerManager
    {
        [DataObjectMethod(DataObjectMethodType.Select, false)]
        public static Customer[] GetCustomers(int startRowIndex, int maximumRows)
        {
            var finder = new CustomerFinder(new CustomerRepository(), new CustomCache());
            return finder.FindAllCustomers(startRowIndex, maximumRows);
        }
    }
    

    Everything to the right of the "var finder", I'd like to replace with...something else.  But first, I want to remove the dependency from CustomerManager to the specific CustomerFinder implementation.  After all, the CustomerManager doesn't really care about this specific CustomerFinder, but rather just something that finds customers.  Let's perform the Extract Interface refactoring on CustomerFinder, by first creating "something that finds customers", an ICustomerFinder:

    public interface ICustomerFinder
    {
        Customer[] FindAllCustomers(int startRowIndex, int maximumRows);
    }
    

    With ReSharper, this refactoring is just a couple of keystrokes away.  Otherwise, I'll:

    • Create the ICustomerFinder interface
    • Copy the signature of the public methods I want in the interface, and paste them in the ICustomerFinder interface
    • Make the CustomerFinder implement the ICustomerFinder interface

    The last part is easy, just add a little section after the class declaration:

    public class CustomerFinder : ICustomerFinder
    

    I don't have to change anything about the CustomerFinder class other than this part.

    Finally, I'll change the CustomerManager method to remove the "var" keyword, making it explicit what the CustomerManager is trying to use:

    [DataObjectMethod(DataObjectMethodType.Select, false)]
    public static Customer[] GetCustomers(int startRowIndex, int maximumRows)
    {
        ICustomerFinder finder = new CustomerFinder(new CustomerRepository(), new CustomCache());
        return finder.FindAllCustomers(startRowIndex, maximumRows);
    }
    

    The GetCustomers method now uses an ICustomerFinder, but creates the whole CustomerFinder mess.  Now we're ready to introduce the fancy factory, StructureMap.

    Introducing StructureMap to the mix

    With our CustomerManager (the class used by an ObjectDataSource to fill a web control) using only an ICustomerFinder, we can concentrate on the right part, the wiring up of dependencies.  We have several options to configure the correct dependencies:

    • XML
    • Attributes
    • Code

    After using StructureMap for some time, I find the code option tends to be the easiest to maintain, because:

    • It's easy to edit
    • It plays nice with refactoring tools
    • It's not XML
    • None of my classes become "infrastructure-aware"
    • All setup is in one place

    With attributes, I can decorate my classes and interfaces, but the configuration is in at least two places with each class.  Sometimes, I don't have access to the underlying interface, so I can't go back and put an attribute on it.

    And XML is well, XML, and therefore automatically more difficult to maintain.  No Intellisense for class names etc. means that typos and such cause problems more often.

    Finding a home

    Now that we've decided on the code route, where should this code go?  We need to put all the configuration in the application startup part.  Since we're using ASP.NET, this means the Global.asax is a good candidate.  We've already downloaded the latest StructureMap release (2.4.9) and added the reference to our ASP.NET project, now we just need to fill it in.

    The basic idea behind our configuration is that we need to tell StructureMap what the interfaces and concrete types are.  Whenever someone asks StructureMap for an instance of a specific type, that type along with all of its dependencies need to be configured.  This means ICustomerFinder, ICustomCache and ICustomerRepository, along with all of the concrete types.

    Here's what I came up with:

    public class Global : HttpApplication
    {
        protected void Application_Start(object sender, EventArgs e)
        {
            StructureMapConfiguration
                .ForRequestedType<ICustomerFinder>()
                .TheDefaultIsConcreteType<CustomerFinder>();
    
            StructureMapConfiguration
                .ForRequestedType<ICustomCache>()
                .TheDefaultIsConcreteType<CustomCache>();
    
            StructureMapConfiguration
                .ForRequestedType<ICustomerRepository>()
                .TheDefaultIsConcreteType<CustomerRepository>();
        }
    }
    

    I put all of my configuration in the Global.asax code-behind, in the Application_Start event.  That way the configuration happens only once at application startup.

    Using the StructureMapConfiguration class, I tell StructureMap each requested type and the concrete type that should be injected.  When someone asks for the ICustomerFinder, StructureMap will create the "real" type of CustomerFinder.  But remember that CustomerFinder only had one constructor that took two other dependencies:

    public CustomerFinder(ICustomerRepository customerRepository, ICustomCache customCache)
    {
        _customerRepository = customerRepository;
        _customCache = customCache;
    }
    

    But since each of these two constructor argument types are also configured in StructureMap, StructureMap is smart enough to wire the whole thing up for us.  Notice we didn't tell StructureMap what to put in specifically into the constructor, it just figured the whole object graph out.

    Now that StructureMap's configured, let's go back to the CustomerManager class to fix that constructor mess.

    Instantiating the component

    With StructureMap, creating an instance configured in StructureMap is a cinch:

    [DataObjectMethod(DataObjectMethodType.Select, false)]
    public static Customer[] GetCustomers(int startRowIndex, int maximumRows)
    {
        ICustomerFinder finder = ObjectFactory.GetInstance<ICustomerFinder>();
        return finder.FindAllCustomers(startRowIndex, maximumRows);
    }
    

    That's it, just the one call to ObjectFactory.GetInstance.  Notice I only used the interface type, and not the concrete type.  Our CustomerManager only really cares about finding customers, not about who actually does the finding.  All it wants to do is ask StructureMap, "Give me something (ICustomerFinder) that can find customers".  CustomerManager doesn't need to care about the concrete CustomerFinder, the caching business or the repository.

    This leads us to a very flexible separation of concerns.  No longer are our classes dependent on specific implementations, but only interfaces that expose a cohesive set of operations.

    Once we have the constructor business out of the way, a quick view at our web applications confirms that the dependencies are wired up correctly.

    Wrapping it up

    We've come a long way since our original example.  The original application had three "tiers", split between an ASPX page, a static method, and LINQ to SQL.  Only one of these classes was something we created, the CustomerManager.

    But this class still had too many responsibilities, which would have given us trouble when we needed to change it.  Now we have many more classes (4 vs. 1) and interfaces (3 vs. 0).  For those who don't like more classes, GET OVER IT.  High cohesion and less coupling means smaller classes with fewer, tighter concerns.  More classes with high cohesion is far easier to maintain, since the responsibilities of each class can be easily discerned.  I've seen far too many one-method classes with thousands of lines in the one method to convince me that more classes is better.

    With separation of concerns in place, along with dependency inversion (dependencies given to the class through the constructor), the responsibilities and dependencies are easy for both clients of the class and maintainers of the class to figure out.  Someone looking at the CustomerFinder class can immediately see it needs a backing store and something with caching to function properly.

    When we ran into a gnarly bug, we were able to diagnose, fix, and lock down the correct behavior with BDD-style behavioral specifications.  As long as our specs are part of a continuous integration process, we can have confidence that the correct behavior won't be undone.

    Separation of concerns is easier with TDD, but TDD won't separate the concerns for us.  It only shows us where the friction and smells are, and it's up to us to decide whether or not to act upon them.  There have been plenty of times I run into a class with too many responsibilities, but can't decide how to break it up.  Later, when more responsibility needs to be added, the picture becomes clear(er) and I then break it up.

    In the end, we care about developing for two people: the people using our software and the people maintaining our software.  Separation of concerns leads to higher maintainability, as we saw in this series.  With high maintainability, we're able to satisfy both camps, as we can change software at a faster, continuous pace.

  • Speaking at ADNUG tonight

    I'm speaking at ADNUG tonight about legacy code:

    The development landscape is strewn with existing legacy systems.  As these systems continue to generate revenue and provide value, eventually some force will act upon the development team to change those systems.  The challenge is to minimize the risk of changing code, while keeping the rest of the system working as-is.  In this talk, we'll cover real-world strategies for dealing with legacy code, uncovering tools and techniques for navigating the minefield of today's systems.  We'll also gain an understanding of the right approaches, strategies and attitudes for dealing with systems held together with duck tape and chewing gum.

    Legacy code is one of my favorite topics, as it's a much maligned topic.  Everyone loves to complain about the resident big ball of mud, but no one wants to change it.  We'll talk about effective tools for making safe changes, while hopefully improving the design as we go.

    The meeting details can be found here:

    From Minefield to Greenfield

    Hope to see you there!

  • ALT.NET Certification course

    I am pleased to announce a new certification course, offered directly by me:

    The Certified ALT.NET Technician (CANT) training course

    As the great composer Burt Bacharach sings:

    What the world needs now, is certs, more certs

    For such a valuable certification, you can expect to pay a low, low price of several thousand dollars for the privilege of an audience with yours truly for 45 minutes, during one of my lunch breaks.  Word of warning: I tend to be late, as the autograph seekers are never sated.  After this course, you will say "Yes I CANT!"

    But why another certification?  Perhaps you didn't listen to my friend Burt earlier.  Agile is already diluted clarified with the Scrum certifications like:

    • Certified ScrumMaster
    • Certified Scrum Product Owner
    • Certified Scrum Practitioner
    • Certified Scrum Coach
    • Certified Scrum Trainer
    • Certified Scrum Lord
    • Certified Scrum Healer
    • Certified Scrum Paladin

    Microsoft has offered their esteemed and renowned certifications for quite awhile now, why should the ALT.NET folks be left out of the mix?  Honestly, we've run out of ways to charge higher consulting fees.  A certification is just the trick to bring our community into the ThoughtWorks realm of consultant rates.

    First, down to business. Let's look at what amazing amount of knowledge this almost hour of instruction will give you.

    Course Details

    Normal technical certifications deal with such worthless endeavors as learning a new technology, new processes or new tools.  We have a far more useful goal not of learning ALT.NET principles, tools and practices, but rather learning about ALT.NET itself.  You can't fully embrace a community without learning the rich and storied history of that community itself.

    Session 1: ALT.NET history

    Contrary to popular belief, ALT.NET started in the jungles of Cambodia, as an elite cadre of trained assassins, bent on world domination and the perfect cup of tea.  Although Chuck Norris severely crippled the ALT.NET community in his illegal but chilling documentary: Braddock: Missing in Action III, our leaders went deep underground to plot their next move.

    That next move was, ironically, a popular uprising against traditional drag and drop development in the mid 2007's.  It is still believed the exorbitant consultant fees will be used in an elaborate plot to re-kidnap Colonel Braddock, as he's skipped the past 18 years of latrine duty in his old prison camp.

    By attending this course, you will be on the ground floor of the diabolical planning, probably used to be Sentry Guard #14 that meets a grisly end from Chuck's blinding roundhouse kick.

    Session 2: ALT.NET Celebs

    You can't talk about ALT.NET without the requisite name-dropping associated with elitist communities.  Far more than who you are and what you do, you'll be judged on how often you mention other ALT.NET celebrities, preferably through regaling with hilarious anecdotes that will leave your fellow coworkers jealous and awestruck.

    We'll introduce you to various ALT.NET luminaries such as:

    Scott Bellware, the Godfather of ALT.NET.  Knowing Scott is key, because love him or hate him, you will agree with him.  Or your CANT card will be torn up, with great ceremony, in the presence of your parents, loved ones, and close friends.  On another note, if you do have the extreme privilege to meet Scott, watch out for Azrael.  It tends to bite, especially if you're wearing predominantly blue.

    Dave Laribee, shown above in his favorite attire and native habitat, is another ALT.NET dignitary that you must count among your friends.  Unless you've played Metastones with the Dave Laribee, you haven't lived.  Dave is also known for his extensive tchotchke collection, including an impressive bevy of bottle caps from around the world.  Dave likes to display his collection neatly stacked in his work cubicle.  Dave is also deaf to the snickers of his fellow coworkers.

    Bil Simser is the self-chosen ALT.NET representative from our wonderful but envious neighbors to the North, Canada.  Bil enjoys endless Canada jokes and impressions, and never tires of questions about Mounties, polar bears and the Iditarod.  But mostly, Bil loves bad Canadian impressions, especially when they start to bleed over into Australian and Kiwi accents.  We've generously allowed Bil to join our community, as technology like computers, the Internet, and modern plumbing have not made their way yet to the Great White North.

    Martin Fowler, mystic, psychic, alchemist, author, supporter of the arts, and wicked Hungry Hungry Hippos opponent.  A general supporter of ALT.NET, but to be a CANT, you must have at least 4 of the Fowler signature series books prominently displayed wherever you may or may not code.  In fact, it's better if you buy a large satchel to carry these sacred tomes, to reference in the likely event a fellow programmer asks for advice.  Which then you must reply, "Well Martin Fowler states that...", followed by a verbatim recitation of previously memorized passages.  These passages don't have to actually relate to the question, as long as they are from a Fowler book.

    These are just a few of the ALT.NET celebrities whose exploits, personalities and personal phone numbers I'll share with you.

    Session 3: Smugness training

    Admission and certification to our egalitarian ALT.NET society cannot be complete without some sound smugness training and practice.  Our exercises will include:

    • Neck strengthening and flexibility training, to better look down your noses on the hoi polloi of the .NET community
    • Introduction into other smug personas, such as vegans, environmentalists, and Bostonians
    • Gentle reminders that you're supporting Big Oil with that gas-guzzling Civic.  How about a Prius mmmmkay?
    • Wearing trendy clothes and hats, such as a nice bowler
    • Five dollar gift card to Whole Foods, because you're going organic.

    Smugness training strengthens the illusion of superiority that all ALT.NET'ers thrive on.  Without this air of superiority, you'll quickly slide into a pattern of self-doubt and self-loathing, and the rest of the community can't survive with fellow members still questioning and searching for better ways of writing software.  We've already found it, so there's no need to keep learning.

    Yes you CANT!

    Join the rest of the obviously superior ALT.NET community, by meeting me at our local Arby's and bringing a signed blank check for the nominal CANT fee, amount to be determined at the end of the course.  As a Certified ALT.NET Technician, you can expect to see 50-75% increases in consultant rates, speaker invitations, book deals, and naturally, a legion of fellow developers desperately clinging to your coattails.  Because if you're not a CANT, you're just another .NET developer.

    Posted Jul 12 2008, 05:16 PM by bogardj with 15 comment(s)
    Filed under:
  • Going lean in Visual Studio

    Left unchecked, Visual Studio tends to get very cluttered:

    I found I don't use any of these icons.  Copy, Cut, Paste, Undo, Redo?  Those are all keyboard shortcuts.  Comment and Uncomment?  Ctrl+K+C, Ctrl+K+U.  Save All?  Ctrl+Shift+S.

    No more, I'm going lean.  None of these toolbars provided me value, taking up valuable screen real estate, so I got rid of them all:

     

    That's about 80 pixels I saved, and about 5 more lines of code are visible.  Beyond that, I'm no longer distracted by a hundred little icons, each hoping they'll be clicked juuuuust once to prove their worth.

    Posted Jul 12 2008, 02:43 PM by bogardj with 9 comment(s)
    Filed under:
  • Separation of Concerns by example: Part 4

    In the last part, we finally broke out the caching and data access concerns from our original class.  The series so far includes:

    Things are looking up, we've broken out the dependencies into distinct concerns, including caching, data access and finding/paging.  Unfortunately, our high-volume site has run into some intermittent issues.  Every now and then, especially during peak hours, the application experiences NullReferenceExceptions, coming from our new and (hopefully) improved CustomerFinder.

    Finding the defect

    Let's review the current CustomerFinder to see how we might run into a NullReferenceException:

    public class CustomerFinder
    {
        private readonly ICustomerRepository _customerRepository;
        private readonly ICustomCache _customCache;
    
        public CustomerFinder(ICustomerRepository customerRepository, ICustomCache customCache)
        {
            _customerRepository = customerRepository;
            _customCache = customCache;
        }
    
        public Customer[] FindAllCustomers(int startRowIndex, int maximumRows)
        {
            Customer[] customers = null;
            string key = "Customers_Customers_" + startRowIndex + "_" + maximumRows;
    
            if (_customCache.Contains(key))
            {
                customers = _customCache.GetItem<Customer[]>(key);
            }
            else
            {
                customers =_customerRepository
                            .FindAllCustomers()
                            .Skip(startRowIndex)
                            .Take(maximumRows)
                            .ToArray();
    
                if ((customers != null) && (customers.Length > 0))
                    _customCache.AddItemExpringTomorrow(key, customers);
            }
    
            return customers;
        }
    
    }
    

    Somehow, our FindAllCustomers method is returning a null Customer array, causing us to break our contract with callers of this class.  Anything that returns an array should never return null, only an empty array if no items are returned.

    So how could the return value be null?  Look at the CustomerFinder class, we see it's initialized to null, and assigned twice.  Once in the caching scenario, and once in the repository scenario.  The repository scenario doesn't seem to fit, as the ToArray extension method never returns null.

    Looking at the caching scenario, combined with our knowledge of when the bug happens, it looks like we might have our culprit. Suppose that under heavy load, the cache item expires between the Contains and GetItem call?  GetItem could certainly return null in that case.  Looking at the Cache documentation, getting an expired (and therefore non-existing) item does not throw any exception, and returns null.

    Let's look at changing the behavior so that we take this scenario into account.

    Making the change (safely)

    Since we'd like to minimize the risk of change to this piece of code (after all, we have a high volume website to keep going), we'll add a test to cover the behavior we want to see, before we make the change.  After all, if the behavior we specify should exist, already does, then either our assumptions are wrong or our code already works.

    First, let's think of the context of when this bug happens.  It occurred when the cache item expired after I checked the cache.  Let's create our specification with that as the description:

    public class When_finding_customers_and_the_cache_expires_after_checking_the_cache 
        : ContextSpecification
    {
        
    }
    

    This is basically a Testcase Class per Feature xUnit pattern, with a BDD-style naming.  Basically, I'm describing the context/scenario where the behavior I want to observe is valid.  The ContextSpecification is similar version of JP's base specification class that I'm using from my pet project, NBehave.

    Now we need to describe the behavior we want to see.  I'd like to see a few things happen:

    • The customers returned shouldn't be null
    • It should use the repository to find the customers (as the cache didn't work)
    • It should push the results back into the cache

    All of these I might write down in an index card or something.  It's something that helps me think through the behaviors I'm trying to specify.  Here's the test class with the behaviors specified:

    public class When_finding_products_and_the_cache_expires_after_checking_the_cache 
        : ContextSpecification
    {
        [Test]
        public void Customers_returned_should_not_be_null()
        {
        }
    
        [Test]
        public void It_should_use_the_repository_to_find_the_customers()
        {
        }
    
        [Test]
        public void Customers_returned_should_be_stored_in_the_cache()
        {
        }
    }
    

    With Rhino Mocks 3.5, testing these indirect inputs and outputs is a snap.  Now that we have our specifications, let's establish the context, the reason for the behaviors, and fill out our verification of the desired behaviors:

    public class When_finding_products_and_the_cache_expires_after_checking_the_cache 
        : ContextSpecification
    {
        private CustomerFinder _customerFinder;
        private Customer[] _actualCustomers;
        private ICustomerRepository _customerRepository;
        private ICustomCache _customCache;
    
        protected override void EstablishContext()
        {
            _customCache = Dependency<ICustomCache>();
            _customerRepository = Dependency<ICustomerRepository>();
    
            _customerFinder = new CustomerFinder(_customerRepository, _customCache);
    
            var customer1 = new Customer {CustomerID = "1"};
            var customer2 = new Customer {CustomerID = "2"};
    
            var foundCustomers = new[]
                                     {
                                         customer1,
                                         customer2
                                     }
                                     .AsQueryable()
                                     .OrderBy(cust => cust.CustomerID);
    
            _customCache.Stub(cache => cache.Contains("Customers_Customers_1_1")).Return(true);
            _customCache.Stub(cache => cache.GetItem<Customer[]>("Customers_Customers_1_1")).Return(null);
            _customerRepository.Stub(repo => repo.FindAllCustomers()).Return(foundCustomers);
        }
    
        protected override void Because()
        {
            _actualCustomers = _customerFinder.FindAllCustomers(1, 1);
        }
    
        [Test]
        public void Customers_returned_should_not_be_null()
        {
            _actualCustomers.ShouldNotBeNull();
        }
    
        [Test]
        public void It_should_use_the_repository_to_find_the_customers()
        {
            _customerRepository.AssertWasCalled(repo => repo.FindAllCustomers());
        }
    
        [Test]
        public void Customers_returned_should_be_stored_in_the_cache()
        {
            _customCache.AssertWasCalled(cache => cache.AddItemExpringTomorrow<Customer[]>(null, null),
                option => option.Constraints(Is.Equal("Customers_Customers_1_1"), 
                                             Is.Matching<Customer[]>(item => item.Length == 1)));
        }
    
    }
    

    With Rhino Mocks new Arrange Act Assert syntax, it's much easier to separate the specifications into the context, reason, and verification of the behavior.  In TDD terms, I've separated the Setup, Exercise, and Assert into three different parts.  Each behavior is verified independently of the other.

    Running my specification through TestDriven.NET tells me that all three behaviors don't work yet, and I need to modify my CustomerFinder to get them green again.  Here's my CustomerFinder after the changes:

    public class CustomerFinder
    {
        private readonly ICustomerRepository _customerRepository;
        private readonly ICustomCache _customCache;
    
        public CustomerFinder(ICustomerRepository customerRepository, ICustomCache customCache)
        {
            _customerRepository = customerRepository;
            _customCache = customCache;
        }
    
        public Customer[] FindAllCustomers(int startRowIndex, int maximumRows)
        {
            Customer[] customers = null;
            string key = "Customers_Customers_" + startRowIndex + "_" + maximumRows;
    
            if (_customCache.Contains(key))
            {
                customers = _customCache.GetItem<Customer[]>(key);
            }
    
            if (customers == null)
            {
                customers =_customerRepository
                            .FindAllCustomers()
                            .Skip(startRowIndex)
                            .Take(maximumRows)
                            .ToArray();
    
                if ((customers != null) && (customers.Length > 0))
                    _customCache.AddItemExpringTomorrow(key, customers);
            }
    
            return customers;
        }
    
    }
    

    Here, I broke out the if/else into two if statements, where the repository search would still occur if the cache retrieval fails.  Going back to my specification, I see that all behaviors are working now.  It looks like our fix is ready to go into production.

    Quick Review

    In the original CustomerFinder, this kind of behavioral specification would have been impossible because of the coupling with ASP.NET Cache and LINQ to SQL.  By breaking out dependencies, I was able to make changes safely to the existing behavior by creating specifications that could mock and stub out any test doubles.  To do so, we:

    • Created a test fixture, naming it after the context of our bug
    • Added specification methods for the behavior we wanted to observe
    • Filled out the context, reason, and verification of the desired behavior

    If the dependencies hadn't been broken out, I would have been in the "Edit and Pray" mode of changing code.  This kind of bug only shows up in production, so it could be quite expensive if I had to make a blind change (and I was wrong).  Breaking the dependencies out allows me to use Test Doubles in place of the real dependencies, allowing me to tweak the indirect inputs and outputs to my CustomerFinder.

    Next time, we'll look at how we can better manage the creation and dependency lookup of our CustomerFinder through an Inversion of Control container.

  • Entities and the Law of Demeter

    The Law of Demeter, and its corresponding code smell, Inappropriate Intimacy, are some of the best bang-for-your-buck code smells that you can address.  The basic idea behind each of these concepts is code related to an object should probably be inside that object.  It's also known as the Principle of Least Knowledge, and I've found it very helpful in creating objects with rich behavior.

    It's not always something I catch immediately, but I tend to notice later.  For example, I noticed this code in one of my code behinds:

    protected decimal GetTotal()
    {
        return _cart
                 .GetItems()
                 .Sum(item => item.Price * item.Quantity);
    }
    

    This method was then called by markup in the template file to display the current total in the cart.

    Now, it seems rather obvious that something like the cart's total should belong on the ShoppingCart object itself.  In some situations, there might not even be a ShoppingCart class, only a generic list of ShoppingCartItems.  In that case, the best thing to do would be to create the ShoppingCart class, if nothing else than to become a magnet for cart behavior.

    With the Move Method refactoring, I moved this behavior to the ShoppingCart class:

    public class ShoppingCart
    {
        private readonly List<ShoppingCartItem> _items;
    
        public ShoppingCart()
        {
            _items = new List<ShoppingCartItem>();
        }
    
        public ShoppingCartItem[] GetItems()
        {
            return _items.ToArray();
        }
    
        public void AddItem(Product product, int quantity)
        {
            var item = new ShoppingCartItem(product);
            item.Quantity = quantity;
            _items.Add(item);
        }
    
        public decimal GetTotal()
        {
            return _items.Sum(item => item.Price * item.Quantity);
        }
    
    }
    

    Again, it seems like more total behavior is in the wrong place.  Why should ShoppingCart have to perform the price/quantity calculation?  Let's move this to the ShoppingCartItem class:

    public class ShoppingCartItem
    {
        private readonly Product _product;
    
        public ShoppingCartItem(Product product)
        {
            _product = product;
        }
    
        public int Quantity { get; set; }
    
        public decimal Price
        {
            get { return _product.Price; }
        }
    
        public Product Product
        {
            get { return _product; }
        }
    
        public decimal GetItemTotal()
        {
            return Quantity * Price;
        }
    }
    

    I also noticed several other places that cared way too much about the Product class.  Here's an example I found in the code-behind:

    protected decimal CalculateMargin(ShoppingCartItem item)
    {
        return item.Product.Price / item.Product.Cost;
    }
    

    Again, this is probably obvious to a lot of people (except me).  This many dots poking into the ShoppingCartItem means the code behind class cares much too deeply about the inner workings of the ShoppingCartItem.  Something like a margin seems like a fundamental concept of a Product, so let's just move it there:

    public class Product
    {
        public string Name { get; set; }
        public decimal Price { get; set; }
        public decimal Cost { get; set; }
    
        public decimal CalculateMargin()
        {
            return Cost == 0 ? 0m : Price / Cost;
        }
    }
    

    I would also create a delega