Unit Testing – Layer of Indirection

Introduction

One unit test pattern The Art of Unit Testing, 2nd edition discusses is the layer of indirection pattern (this is my name for the pattern since the book does not give it a name). Its purpose like many other patterns in the book is to make your code less dependent on objects you have little or no control over. I find that adding a layer of indirection to an object is effective an effective technique when the dependency is difficult to fake.

Repository Example

Imagine you had to test the repository class shown in Listing 1. The repository is dependent on the Context class and the IEntity interface. The Context class is derived from DbContext and is shown in Listing 2. The IEntity interface and the Customer class that derives from it are shown in Listing 3.

public class Repository<TEntity, TId> where TEntity : class, IEntity<TId> where TId : IComparable<TId>
    {
        private readonly Context context;

        public Repository(Context context)
        {
            this.context = context;
        }

        public TEntity GetSingle(TId id)
        {
            var comparable = id as IComparable<TId>;
            return this.context.Set<TEntity>().AsEnumerable().Single(e => comparable.CompareTo(e.Id) == 0);
        }

        public IEnumerable<TEntity> GetMany(Func<TEntity, bool> criteria)
        {
            return this.context.Set<TEntity>().AsEnumerable().Where(criteria);
        }
    }

Listing 1


public class Context : DbContext
    {
        public Context() : base("context")
        {
            
        }

        public DbSet<Customer> CustomerSet { get; set; }
    }

Listing 2

public interface IEntity<TId> where TId : IComparable<TId>
    {
        TId Id { get; set; }
    }

public class Customer : IEntity<int>
    {
        public int Id { get; set; }

        public string FirstName { get; set; }

        public string LastName { get; set; }
    }

Listing 3

Obviously the repository class is not unit-testable as it has a dependency on the Entity Framework. I find that the strategy most start out with is to figure out a way to inject a fake DbContext into the repository. An example of this approach can be found here. This strategy is overly complex and it would be easier to write integration tests against a real database as shown in Listing 4. Eventually I would tire of this approach as I had to support more entities and repositories. Most importantly, the extra code doesn’t help me vet the design. In other words, it is easy to lose the forest for the trees when trying to fake DbContext .

[TestClass]
    public class CustomerRepositoryIntegrationTests
    {
        [AssemblyInitialize]
        public static void AssemblyInitialize(TestContext testContext)
        {
            Database.SetInitializer(new DropCreateDatabaseAlways<Context>());
            new Context().Database.Initialize(true);
        }

        [TestMethod]
        public void GetSingle_ReturnsTheCustomer()
        {
            var context = new Context();
            var repo = new Repository<Customer, int>(context);
            
            using (new TransactionScope(TransactionScopeOption.Required))
            {
                var customer = new Customer();
                context.CustomerSet.Add(customer);
                context.SaveChanges();

                var customerId = customer.Id;
                Assert.AreEqual(customerId, repo.GetSingle(customerId).Id);
            }
        }

        [TestMethod]
        public void GetMany_ReturnsTheCustomers()
        {
            var context = new Context();
            var repo = new Repository<Customer, int>(context);

            using (new TransactionScope(TransactionScopeOption.Required))
            {
                var customers = new[] { new Customer(), new Customer() };
                context.CustomerSet.AddRange(customers);
                context.SaveChanges();

                Assert.AreEqual(2, repo.GetMany(c => string.IsNullOrWhiteSpace(c.FirstName)).Count());
            }
        }
    }

Listing 4

By adding a layer of indirection, you can break the dependency between the repository and Entity Framework without resorting to an integration test only approach, in-memory databases or obscure tools. The only tool you need is a free mocking framework like NSubstitute.

Layer of Indirection Example

The IRepositoryDataSource interface shown in Listing 5 is the layer of indirection. Listing 6 shows the modified Repository class that makes use of the new interface. Since the Entity Framework dependency is gone, the class is unit-testable. The simplified unit tests are shown in Listing 7. The unit tests use NSubstitute to do the faking.

public interface IRepositoryDataSource<TEntity, TId> where TEntity : class, IEntity<TId> where TId : IComparable<TId>
    {
        IEnumerable<TEntity> Entities { get; }  
    }

Listing 5

public class Repository<TEntity, TId> where TEntity : class, IEntity<TId> where TId : IComparable<TId>
    {
        private readonly IRepositoryDataSource<TEntity, TId> dataSource;

        public Repository(IRepositoryDataSource<TEntity, TId> dataSource)
        {
            this.dataSource = dataSource;
        }

        public TEntity GetSingle(TId id)
        {
            var comparable = id as IComparable<TId>;
            return this.dataSource.Entities.Single(e => comparable.CompareTo(e.Id) == 0);
        }

        public IEnumerable<TEntity> GetMany(Func<TEntity, bool> criteria)
        {
            return this.dataSource.Entities.Where(criteria);
        }
    }

Listing 6

[TestClass]
    public class CustomerRepositoryUnitTests
    {
        [TestMethod]
        public void GetSingle_ReturnsTheCustomer()
        {
            var customer = new Customer { Id = 1 };
            
            var fakeDataSource = Substitute.For<IRepositoryDataSource<Customer, int>>();
            fakeDataSource.Entities.Returns(new[] { customer });

            var repository = new Repository<Customer, int>(fakeDataSource);
            repository.GetSingle(customer.Id);
        }

        [TestMethod]
        public void GetMany_ReturnsTheCustomers()
        {
            var customers = new[] { new Customer(), new Customer() };

            var fakeDataSource = Substitute.For<IRepositoryDataSource<Customer, int>>();
            fakeDataSource.Entities.Returns(customers);

            var repository = new Repository<Customer, int>(fakeDataSource);
            Assert.AreEqual(2, repository.GetMany(c => string.IsNullOrWhiteSpace(c.FirstName)).Count());
        }
    }

Listing 7

Now that the unit tests have vetted the design, a “real” repository data source can be written. This class is shown in Listing 8. Listing 9 shows the amended integration tests that use the RepositoryDataSource class.

public class RepositoryDataSource<TEntity, TId> : IRepositoryDataSource<TEntity, TId> where TEntity : class, IEntity<TId> where TId : IComparable<TId>
    {
        private readonly DbContext context;

        public RepositoryDataSource(DbContext context)
        {
            this.context = context;
        }

        public IEnumerable<TEntity> Entities
        {
            get
            {
                return this.context.Set<TEntity>().AsEnumerable();
            }
        }
    }

Listing 8

[AssemblyInitialize]
        public static void AssemblyInitialize(TestContext testContext)
        {
            Database.SetInitializer(new DropCreateDatabaseAlways<Context>());
            new Context().Database.Initialize(true);
        }

        [TestMethod]
        public void GetSingle_ReturnsTheCustomer()
        {
            var context = new Context();
            var dataSource = new RepositoryDataSource<Customer, int>(context);
            var repo = new Repository<Customer, int>(dataSource);

            using (new TransactionScope(TransactionScopeOption.Required))
            {
                var customer = new Customer();
                context.CustomerSet.Add(customer);
                context.SaveChanges();

                var customerId = customer.Id;
                Assert.AreEqual(customerId, repo.GetSingle(customerId).Id);
            }
        }

        [TestMethod]
        public void GetMany_ReturnsTheCustomers()
        {
            var context = new Context();
            var dataSource = new RepositoryDataSource<Customer, int>(context);
            var repo = new Repository<Customer, int>(dataSource);

            using (new TransactionScope(TransactionScopeOption.Required))
            {
                var customers = new[] { new Customer(), new Customer() };
                context.CustomerSet.AddRange(customers);
                context.SaveChanges();

                Assert.AreEqual(2, repo.GetMany(c => string.IsNullOrWhiteSpace(c.FirstName)).Count());
            }
        }

Listing 9

The Need for Integration Testing

Integration tests are still necessary because you still need to see how the system works with real dependencies at some point. Also having separate unit and integration tests create a “safe green zone” as The Art of Unit Testing puts it. Basically this means you can run unit tests many times a day and they should always pass (green). Integration tests are probably not run as often because they usually take longer and they may need a deployable build to work.

Conclusion

When a difficult to fake object is making unit testing difficult, consider adding a layer of indirection. This allows you to create an interface around the difficult to fake object that you control. This control allows you to do away with the dependency. Again, this pattern is discussed in detail in the The Art of Unit Testing, 2nd edition. I recommend reading the book from cover to cover.

Advertisements

Unity.WebAPI NuGet Package Breaks the HttpSelfHostConfiguration Class

If you are using the HttpSelfHostConfiguration class that derives from HttpConfiguration, be careful when adding the Unity.WebAPI NuGet package to your project. The package adds a newer version of System.Web.Http.dll (where HttpConfiguration resides) which doesn’t play nice with System.Web.Http.SelfHost.dll (where HttpSelfHostConfiguration resides). Specifically, attempting to create an instance of the HttpSelfHostConfiguration class will fail with the following exception:


Initialization method CarSite.IntegrationTests.Advertisement_Is_Added threw exception. System.TypeLoadException: System.TypeLoadException: Inheritance security rules violated by type: ‘System.Web.Http.SelfHost.HttpSelfHostConfiguration’. Derived types must either match the security accessibility of the base type or be less accessible..

After a few hours of searching, I came across this MSDN article. The “Inheritance Rules” section of the article shows a matrix of compatible rules. I decompiled both versions of System.Web.Http.dll so I could see their respective assembly attributes. The one important difference I saw was the lack of the following attribute (or any security related attributes) for that matter in the newer System.Web.Http.dll which the NuGet package placed:

[assembly: AllowPartiallyTrustedCallers]

I believe the absence of this attribute (orSecurityTransparent or SecuritySafeCritical) means that the code in the new System.Web.Http assembly is “Critical.” Therefore, derived classes must also be treated as critical code. This not the case because of this attribute present in the System.Web.Http.SelfHost assembly:

[assembly: SecurityTransparent]

According to the matrix, the error makes sense. However, what is not clear to me is the statement in “Assemblywide Annotation” section of the same MSDN article. It states that the following:

“Specifying no attribute causes the common language runtime to determine the transparency rules for you. All types and members are security-critical, except where being security-critical violates an inheritance rule.”

If we’re supposed to take the second sentence as meaning a derived class can be more restrictive than the base class, then the exception makes sense.

If you need to use Unity along with the HttpSelfHostConfiguration class, you are better off doing it without the NuGet package. It’s pretty easy so you’re not going to lose too much productivity or maintenance-wise.

For the specific scenario where I encountered this issue, please see this post.

IIS-Free ASP.NET MVC Web API Integration Testing

Introduction

If you’re like me and think running an IIS server (including IIS Express and the Visual Studio web server) just to integration test your web API is a pain, please read on. In this post, I describe how to self-host a web api. Fortunately the design of ASP.NET MVC Web API makes self-hosting easy.

The Web API

Listing 1 shows the code for the simple web API used in this post. It consists of a single controller implementing a POST method. The method adds a car advertisement to the site. Notice there is no default constructor which can only mean we’re going to talk about dependency injection at some point.

public class AdvertisementController : ApiController
    {
        private readonly ICarSiteRepository repository;

        public AdvertisementController(ICarSiteRepository repository)
        {
            this.repository = repository;
        }

        public HttpResponseMessage Post(HttpRequestMessage request, Advertisement advertisement)
        {
            this.repository.AddAdvertisement(advertisement);
            var response = request.CreateResponse(HttpStatusCode.Created);
            response.Headers.Location = new Uri(Url.Link("DefaultApi", new { id = Guid.NewGuid().ToString("N") }));
            return response;
        }
    }

Listing 1

The Repository

The ICarSiteRepository defines the contract for adding advertisements to the site. It consists of a single method which takes an Advertisement instance. The interface’s definition is shown in Listing 2.

public interface ICarSiteRepository
    {
        void AddAdvertisement(Advertisement adverstisement);
    }

Listing 2

The Model

The Advertisement class is the only model class. Its code is shown in Listing 3.

public class Advertisement
    {
        public Guid Id { get; set; }
        public string Make { get; set; }
        public string Model { get; set; }
        public int Year { get; set; }
        public string Description { get; set; }
    }

Listing 3

Now we’ll cover testing the controllers Post method.

The Self-hosted HTTP Server

In order to test web API methods without IIS, we will need to write an HTTP server. That sounds like more trouble than it is worth, but it is actually quite easy. Keep in mind that we want to have the minimum functionality that will allow us to test web API methods. Listing 4 shows the code.

public class SelfHostHttpServer : IDisposable
    {
        private bool disposed;
        private HttpSelfHostServer server;
       
        public SelfHostHttpServer(Action<HttpConfiguration> configurationHandler, string baseUrl)
        {
            if (configurationHandler == null)
            {
                throw new ArgumentNullException("configurationHandler", "Value cannot be null or empty.");
            }

            if (string.IsNullOrWhiteSpace(baseUrl))
            {
                throw new ArgumentException("Value cannot be null or empty.", "baseUrl");
            }

            this.InitializeServer(configurationHandler, baseUrl);
        }

        public HttpResponseMessage Send(HttpRequestMessage request)
        {
            return new HttpClient().SendAsync(request).Result;
        }

        public void Dispose()
        {
            this.Dispose(true);
            GC.SuppressFinalize(this);
        }

        private void Dispose(bool disposing)
        {
            if (!this.disposed)
            {
                if (disposing)
                {
                    if (this.server != null)
                    {
                        this.server.Dispose();
                        this.server = null;
                    }
                }

                this.disposed = true;
            }
        }

        private void InitializeServer(Action<HttpConfiguration> configurationHandler, string baseUrl)
        {
            var config = new HttpSelfHostConfiguration(baseUrl);
            configurationHandler(config);
            this.server = new HttpSelfHostServer(config);
            this.server.OpenAsync().Wait();
        }

Listing 4

The interesting code is in the InitializeServer method. All you need to do in order to get a functional HTTP server is do the following:

  1. Create an instance of the HttpSelfHostConfiguration class.
  2. Call the static WebApiConfig.Register method. This is done via a delegate for reusability.
  3. Create an instance of the HttpSelfHostServer class, passing in the HttpSelfHostConfiguration instance.
  4. Call OpenAsync to make the server listen for requests.

Our tests will call the server’s Send method when a request needs to be sent to the server. Send simply creates an HttpClient instance, sends the request to the server, and sends the response back.

The Test

Test test class is shown in Listing 5.

[TestClass]
    public class When_Calling_The_AdvertisingController
    {
        private const string BaseUrl = "http://localhost/baseUrl/";
        private static MediaTypeFormatter formatter = new JsonMediaTypeFormatter();
        private static SelfHostHttpServer server;
        private TestContext testContextInstance;

        public TestContext TestContext
        {
            get
            {
                return testContextInstance;
            }
            set
            {
                testContextInstance = value;
            }
        }

        [ClassInitialize]
        public static void ClassInitialize(TestContext testContext)
        {
            server = new SelfHostHttpServer(WebApiConfig.Register, BaseUrl);
            Assert.IsNotNull(server);
        }

        [TestMethod]
        public void The_New_Advertisement_Is_Added()
        {
            var advertisement = new Advertisement
                                    {
                                        Year = 2013,
                                        Make = "Audi",
                                        Model = "S8",
                                        Description = "Check it out!"
                                    };

            var request = new HttpRequestMessage(HttpMethod.Post, BaseUrl + "/api/advertisement")
                              {
                                  Content = new ObjectContent<Advertisement>(advertisement, formatter)
                              };

            var response = server.Send(request);
            this.TestContext.WriteLine("Response content:{0}{1}", Environment.NewLine, response.Content.ReadAsStringAsync().Result);
            Assert.AreEqual(HttpStatusCode.Created, response.StatusCode);
        }
    }

Listing 5

The single test method creates a request, sends it to the HTTP server, and verifies the response. At this point the test will fail. The response’s content contains the following JSON:

{
  "Message": "An error has occurred.",
  "ExceptionMessage": "Type 'CarSite.Api.Controllers.AdvertisementController' does not have a default constructor",
  "ExceptionType": "System.ArgumentException",
  "StackTrace": "   at System.Linq.Expressions.Expression.New(Type type)\r\n   at System.Web.Http.Internal.TypeActivator.Create[TBase](Type instanceType)\r\n   at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.GetInstanceOrActivator(HttpRequestMessage request, Type controllerType, Func`1& activator)\r\n   at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType)"
}

The response should come as no surprise since the API has not been given an ICarSiteRepository. We can easily mock this but how do we get it to the controller? We’ll need to associate an IDependencyResolver implementation to the HttpSelfHostConfiguration. We will use Microsoft Unity’s dependency resolver and container.

Unity.WebAPI NuGet Package

I install this package whenever I need to incorporate Unity in my web API projects. However, this is not a good idea when self-hosting. See this post for the trouble it causes. Fortunately, Unity itself has the UnityDependencyResolver class which is an implementation of IDependencyResolver.

By the way, install a mocking framework as well via NuGet. We will pass a mocked implementation of ICarSiteRepository. I am going to use RhinoMocks.

Microsoft Unity NuGet Package

Search NuGet for “Unity” and install it. Using Unity with our self-hosted server is simply a matter of configuring a UnityContainer instance, registering the types, passing it to a UnityDependencyResolver instance, and associating the resolver with the server’s HttpSelfHostConfiguration.

We’re going to inject the IDependencyResolver into the HTTP server so change the code so it looks like Listing 6.

private bool disposed;
        private HttpSelfHostServer server;
       
        public SelfHostHttpServer(Action<HttpConfiguration> configurationHandler, string baseUrl, IDependencyResolver dependencyResolver)
        {
            if (configurationHandler == null)
            {
                throw new ArgumentNullException("configurationHandler", "Value cannot be null or empty.");
            }

            if (string.IsNullOrWhiteSpace(baseUrl))
            {
                throw new ArgumentException("Value cannot be null or empty.", "baseUrl");
            }

            this.InitializeServer(configurationHandler, baseUrl, dependencyResolver);
        }

        public HttpResponseMessage Send(HttpRequestMessage request)
        {
            return new HttpClient().SendAsync(request).Result;
        }

        public void Dispose()
        {
            this.Dispose(true);
            GC.SuppressFinalize(this);
        }

        private void Dispose(bool disposing)
        {
            if (!this.disposed)
            {
                if (disposing)
                {
                    if (this.server != null)
                    {
                        this.server.Dispose();
                        this.server = null;
                    }
                }

                this.disposed = true;
            }
        }

        private void InitializeServer(Action<HttpConfiguration> configurationHandler, string baseUrl, IDependencyResolver dependencyResolver)
        {
            var config = new HttpSelfHostConfiguration(baseUrl);

            if (dependencyResolver != null)
            {
                config.DependencyResolver = dependencyResolver;
            }

            configurationHandler(config);
            this.server = new HttpSelfHostServer(config);
            this.server.OpenAsync().Wait();
        }
    }

Listing 6

As we’re going to create the dependency resolver in the test class, we’ll need to install the Unity bootstrapper for ASP.NET Web API package via NuGet because the Unity package doesn’t contain the assembly we need. Search NuGet for “Unity bootstrapper” and install.

Edit the test class’s ClassInitialize method so it looks like Listing 7.

[ClassInitialize]
        public static void ClassInitialize(TestContext testContext)
        {
            var container = new UnityContainer();
            
            container.RegisterInstance(
                typeof(ICarSiteRepository),
                MockRepository.GenerateMock<ICarSiteRepository>(),
                new HierarchicalLifetimeManager());

            var resolver = new UnityDependencyResolver(container);

            server = new SelfHostHttpServer(WebApiConfig.Register, BaseUrl, resolver);
            Assert.IsNotNull(server);
        }

Listing 7

Run the test and it should pass. You now have an infrastructure that allows you to test your web API without needing IIS!

Entity Framework 6 Weirdness

I used NuGet to install Entity Framework for a new project. To my surprise Entity Framework 6 was installed and version 5 is no longer available. The configuration file is certainly more complicated than it was in version 5. You are now required to have the entityFramework section in the application configuration file even if you are working with code-first.

So I was seeing the following error when running a test that inserted an entity into my database:

Unable to create instance of class PingYourPackage.Data.Tests.Repositories.And_Working_With_Roles. Error: System.InvalidOperationException: The Entity Framework provider type ‘System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer’ registered in the application config file for the ADO.NET provider with invariant name ‘System.Data.SqlClient’ could not be loaded. Make sure that the assembly-qualified name is used and that the assembly is available to the running application. See http://go.microsoft.com/fwlink/?LinkId=260882 for more information..

I went to the link in the error message and verified the configuration file was properly written during the NuGet package installation. I also saw that a reference had been added to EntityFramework.SqlServer.dll. I opened the assembly in Object Browser and verified that System.Data.Entity.SqlServer.SqlProviderServices was indeed present.

The stack trace was pretty deep, but it started in my DbContext derived class’s constructor:

at System.Data.Entity.DbContext..ctor(String nameOrConnectionString)
at MyAssembly.Data.MyDbContext..ctor()

I figured I try load the type myself so I put in this code in my DbContext derived class’s static constructor:

// Without this line, EF6 will break.
var type = typeof(System.Data.Entity.SqlServer.SqlProviderServices);

Problem solved.

My configuration file is shown below for reference. Note than with Entity Framework 5, I only needed the connection string section when working with code-first.

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <configSections>
    <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
  <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 --></configSections>
  <connectionStrings>
    <add name="MyDatabase" connectionString="Data Source =.;Initial Catalog=MyDatabase;Integrated Security=True" providerName="System.Data.SqlClient"  />
  </connectionStrings>
  <entityFramework>
    <providers>
      <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
    </providers>
  </entityFramework>
</configuration>

Exclude Source Files From StyleCop Analysis

StyleCop is a useful tool that helps development teams establish coding standards per Microsoft best practices. Unfortunately, you will likely be inundated with hundreds of warnings if you run it on an existing codebase. I recently ran it on a solution which I inherited and Visual Studio displayed 1000 warnings. There are likely more and 1000 is the Visual Studio limit.

Here is a nice post on how to exclude files from being analyzed by StyleCop. By implementing this process, you can have StyleCop analyze only new files, which will hopefully lead to faster adoption since you won’t be confronted with hundreds of warnings at the outset.

The serviceSecurityAudit Service Behavior

The serviceSecurityAudit service behavior helped me figure out an exception I was receiving from my WCF service. As shown below, the exception was not very helpful:

System.ServiceModel.Security.MessageSecurityException occurred
  HResult=-2146233087
  Message=An unsecured or incorrectly secured fault was received from the other party. See the inner FaultException for the fault code and detail.
  Source=mscorlib
  StackTrace:
    Server stack trace:
       at System.ServiceModel.Channels.SecurityChannelFactory`1.SecurityRequestChannel.ProcessReply(Message reply, SecurityProtocolCorrelationState correlationState, TimeSpan timeout)
       at System.ServiceModel.Channels.SecurityChannelFactory`1.SecurityRequestChannel.Request(Message message, TimeSpan timeout)
       at System.ServiceModel.Security.SecuritySessionSecurityTokenProvider.DoOperation(SecuritySessionOperation operation, EndpointAddress target, Uri via, SecurityToken currentToken, TimeSpan timeout)
       at System.ServiceModel.Security.SecuritySessionSecurityTokenProvider.GetTokenCore(TimeSpan timeout)
       at System.IdentityModel.Selectors.SecurityTokenProvider.GetToken(TimeSpan timeout)
       at System.ServiceModel.Security.SecuritySessionClientSettings`1.ClientSecuritySessionChannel.OnOpen(TimeSpan timeout)
       at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
       at System.ServiceModel.Channels.ServiceChannel.OnOpen(TimeSpan timeout)
       at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
    Exception rethrown at [0]:
       at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
       at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
       at System.ServiceModel.ICommunicationObject.Open(TimeSpan timeout)
       at System.ServiceModel.ClientBase`1.System.ServiceModel.ICommunicationObject.Open(TimeSpan timeout)
       at System.ServiceModel.ClientBase`1.Open()
       at ProductsClient2.Program.Main(String[] args) in c:\Users\farooqm\Documents\Visual Studio 2012\Projects\WCF 4 Step By Step\Chapter 5\ProductsClient2\Program.cs:line 32
  InnerException: System.ServiceModel.FaultException
       HResult=-2146233087
       Message=An error occurred when verifying security for the message.
       InnerException:

Enter serviceSecurityAudit to the rescue. You can configure this to write security related service events to the Windows Event Log. Simply add the code in Listing 1.

  
<servicebehaviors>
     <behavior name="MyService_serviceSecurityAuditBehavior">
          <servicesecurityaudit 
               auditloglocation="Application" 
               serviceauthorizationauditlevel="SuccessOrFailure" 
               messageauthenticationauditlevel="SuccessOrFailure" />
     </behavior>
</servicebehaviors> 

Listing 1

Now when the service fails, take a look at the errors in the Windows Application Event Log. Listing 2 shows the messages seen in a PowerShell session.

 

PS C:\windows\system32> get-eventlog -logname application -entrytype error -newest 10 | fl message

Message : Message authentication failed.          
          Service: https://farooqmelite3/InternetProductsService/ProductService.svc
          Action: http://docs.oasis-open.org/ws-sx/ws-trust/200512/RST/SCT
          ClientIdentity: 
          ActivityId: <null>
          SqlException: An attempt to attach an auto-named database for file C:\Users\farooqm\Documents\Visual Studio 
          2012\Projects\WCF 4 Step By Step\Chapter 5\ProductsService\App_Data\aspnetdb.mdf failed. A database with the 
          same name exists, or specified file cannot be opened, or it is located on UNC share.

Listing 2

Turns out the application pool’s identity did not have permissions to create the ASP.NET membership provider database. Changing the identity to a different account resolved the issue as shown by the event log entries in Listing 3.

 

PS C:\windows\system32> get-eventlog -logname application -entrytype information -source "ServiceModel Audit 4.0.0.0" -newest 10 | fl message
Message : Impersonation succeeded.
          MethodName: GetProductNumbers
          ClientIdentity: bubba
          ActivityId: <null>
		  
Message : Service authorization succeeded.
          Service: https://farooqmelite3/InternetProductsService/ProductService.svc
          Action: http://tempuri.org/IProductService/GetProductNumbers
          ClientIdentity: bubba
          AuthorizationContext: uuid-2db2091a-8226-4e3d-a422-1720388491a0-1
          ActivityId: <null>
          ServiceAuthorizationManager: <default>

Message : Message authentication succeeded.
          Service: https://farooqmelite3/InternetProductsService/ProductService.svc
          Action: http://tempuri.org/IProductService/GetProductNumbers
          ClientIdentity: bubba
          ActivityId: <null>

Message : Message authentication succeeded.
          Service: https://farooqmelite3/InternetProductsService/ProductService.svc
          Action: http://docs.oasis-open.org/ws-sx/ws-trust/200512/RST/SCT
          ClientIdentity: bubba
          ActivityId: <null>

Listing 3

Hopefully, you will find the serviceSecurityAudit saves you time troubleshooting security related issues with your WCF service.

MVC Pattern

Introduction

Recently, I was at Half-Price Books where Pro ASP.NET 4 in C# 2010  by Matthew McDonald, et al was sitting (at more than half-off the retail price, by the way). I started to thumb through the book and in Chapter 12, we learn how to build a simple file browser web application. The code was simple enough and I started thinking about the MVC pattern and how I could adapt this example to use MVC. I conceptually understand the MVC pattern and why it helps. However, I do have questions and concerns about it, mostly around the model. Isn’t it just the business logic layer or a data layer? In other words, to me it didn’t seem like it was directly tied into the presentation. Why does it specifically need to be part of this pattern? It seems to me that the view and controller should be sufficient and the model seemed extraneous. Second, the controller is just a forwarder for the view. Why couldn’t the controller do more? These questions puzzled me the most about the MVC pattern. I put the book back and continued browsing the shelves.

Must have been my lucky day because also on the shelf was Microsoft .NET: Architecting Applications for the Enterprise by Dino Esposito et al. I had borrowed it from the corporate library several times for reference while doing design work. I never looked at Chapter 7 in detail which talks about the presentation layer although I knew it mentioned the MVC pattern. I found a chair and started reading. I never realized that this pattern had such an interesting history. I was also gratified that my MVC questions were answered.

The Original MVC Paradigm

Esposito takes the reader through a history of MVC starting with the original MVC paradigm mentioned in a MVC 1979 paper. Esposito places emphasis on the term “paradigm” as it implies a construct that is amenable to modification and extension as opposed to a pattern which is more firmly rooted. This is probably the reason why there are so many variations of MVC. Figure 1 shows the original MVC pattern as discussed in the paper. The paper refers to the model, view, and controller as the “MVC triad.”

image

         

Figure 1

         

The green lines show the typical sequence of operations with an optional operation in purple. Esposito mentions that the main issue with the original MVC is that the model can communicate with both the controller and the view. In a layered design, lower levels should only communicate with the layer directly above it. In the original MVC, this is not the case. A second issue is that the controller is dependent on a concrete implementation of the view. This makes it difficult for an application to support multiple views or change the view entirely (say from an ASP.NET form to a Windows form). The same holds true for the dependency on the controller on a concrete model implementation.

The Model View Presenter Pattern

The coupling issues inherent in the original formulation of MVC, led to the formation of the Model View Presenter (MVP) pattern. This pattern is first mentioned in this paper. This pattern is a descendant of MVC but gives the controller more power, thus eliminating the coupling of the model to the view. The controller becomes the central figure in the pattern. The view becomes “dumber” because it does not have to interact with the model. The upshot of all this is that the solution becomes more testable. Now that the UI contains code that simply operates on visual elements, the need for automated testing in the view is reduced. The automated testing can now be focused solely on the controller. A second benefit is that the view can be changed (say from a ASP.NET form to a Windows Form) without changing the controller code. Or the same application can provide multiple views based on the same controller. This is possible because the controller is not dependent on the concrete view but on an interface the view exposes. From this, you can see another testing benefit – the view can be mocked. The same holds true for the dependency on the controller to an interface exposed by the model. Figure 2 shows the MVP pattern in action. Yes, the controller becomes more complex but the tradeoff being simpler testing and more flexibility to application changes makes up for it.

image

         

Figure 2

         

Notice the controller is now called the presenter presumably due to its expanded responsibilities. It is also dependent on interfaces exposed by the view and model rather than concrete implementations. Esposito coins the term “presenter-first development” for this characteristic. This makes the view and model amenable to mocking, facilitating automated testing.

So What of the Model?

By this time, my questions concerning the model have been answered. Yes, the model in enterprise applications is the business logic layer (or a data layer for simpler applications). It is not directly related to presentation. MVP also addresses my other concern about the controller playing a larger role and eliminating the dependency between the view and model. Indeed by abstracting the model through an interface, who cares what the model really does now right? The same holds true for the view.

The View and Data Binding

ASP.NET, WPF, and Windows Forms offers a great data binding infrastructure that makes it easy for the presenter to update the view. The question is should the view contain the data binding code at all? The benefit of MVP is a “dumb” view. Does data binding code make it smarter and does that impact testability. In my opinion, this is a judgment call. Data binding certainly reduces complexity. If you are comfortable with not testing the data binding infrastructure then put the data binding code in the view. However, if you feel the need to put data binding logic in the presenter, then put the code in the presenter. Fowler calls these MVP variations Supervising Controller and Passive View respectively. In the case where you need to have complex logic that data binding doesn’t provide, then my opinion is to put that code in the controller where it can be tested.

Presentation Model

Presentation Model is a variant of MVP. It is used in WPF and Silverlight applications. The model in this pattern plays a key role. The model is not the business logic or data layer as it is in MVP. Rather, it contains the state of the view. It is through the model that the view is updated. The view in Presentation Model is “dumb.” It only contains logic to render the controls. The controls’ properties are bound to properties on the model. Figure 3 shows Presentation Model in action. Note that the view and model data binding is bidirectional which WPF supports.

image

         

Figure 3

         

Conclusion

Esposito and Fowler really clarified MVC for me. The driver for the original MVC pattern was separation of concerns. As applications became more complex, MVP was devised to address testability concerns. Presentation Model is a further refinement that incorporates bidirectional data binding which facilitates testing and reduces some of the complexity of implementing a supervising controller. My key takeaway is that as long as the solution you’ve come up with meets the customer’s requirements and is testable, what patterns you use or don’t use is not important.