Spring and Spring.NET

Building Enterprise Frameworks – Testing and Mock Objects

0

This is the third installment of the “Building Enterprise Frameworks” series, which is the evolving design of an enterprise framework. In the series introduction, we presented a problem faced by many enterprise software teams and delivered a plan. The previous blog entry introduced the preliminary data access layer and domain model, which are a collection of abstractions forming a unified framework or infrastructure. In this blog entry, we refactor the data access layer and build the supporting unit tests.

Before covering testing, we will refactor the Repository introduced in the previous installment. At this time, we will eliminate the RepositoryBase abstract class. After testing and coding additional NHibernateRepositoryBase features, this class provided no immediate value to the enterprise framework. The abstract class was moved to the Framework Repository folder, which was vacated by the previous RepositoryBase. We also refactored the Generic interfaces and classes, which better aligns with our technical design and objectives. The following is the revised Framework project structure.

The following is the IRepository interface, which defines the required Repository implementation methods. As discussed in the previous installment, these are the basic Create-Read-Update-Delete (CRUD) operations.

01
using System;
02
using System.Collections.Generic;
03
using Joemwalton.Framework.Domain;
04
 
05
namespace Joemwalton.Framework.Data.Repository
06
{
07
    public interface IRepository<TEntity, TId>
08
        where TEntity : IEntity<TId>
09
    {
10
        void Save(TEntity entity);
11
        void Remove(TEntity entity);
12
        TEntity FindById(TId id);
13
        List<TEntity> FindAll();
14
    }
15
}

Since we eliminated the RepositoryBase abstract class, the NHibernateRepositoryBase will replace the method implementation for our NHibernate base class. The next installment of the “Building Enterprise Frameworks” series will focus on NHibernate and IoC, so the details of the design will not be discussed here – including session and transaction management. The base class will include the CRUD method implementation, so the concrete Repository implementations remain focused on providing domain specific data services. Basically…eliminating redundant code!

01
using System;
02
using System.Collections.Generic;
03
using NHibernate;
04
using NHibernate.Criterion;
05
using Joemwalton.Framework.Data.Repository;
06
using Joemwalton.Framework.Domain;
07
 
08
namespace Joemwalton.Framework.Data.NHibernate
09
{
10
    public abstract class NHibernateRepositoryBase<TEntity, TId> 
11
        : IRepository<TEntity, TId>
12
        where TEntity : IEntity<TId>
13
    {
14
        private ISessionFactory _sessionFactory;
15
 
16
        /// <summary>
17
        /// NHibernate Session Factory
18
        /// </summary>
19
        public ISessionFactory SessionFactory
20
        {
21
            protected get { return _sessionFactory; }
22
            set { _sessionFactory = value; }
23
        }
24
 
25
        /// <summary>
26
        /// Get current active session
27
        /// </summary>
28
        protected ISession CurrentSession
29
        {
30
            get { return this.SessionFactory.GetCurrentSession(); }
31
        }
32
 
33
        public TEntity FindById(TId id)
34
        {
35
            return this.CurrentSession.Get<TEntity>(id);
36
        }
37
 
38
        public List<TEntity> FindAll()
39
        {
40
            ICriteria query = this.CurrentSession.CreateCriteria(typeof(TEntity));
41
            return (List<TEntity>)query.List<TEntity>();
42
        }
43
 
44
        public void Save(TEntity entity)
45
        {
46
            using (ITransaction transaction = this.CurrentSession.BeginTransaction())
47
            {
48
                this.CurrentSession.SaveOrUpdate(entity);
49
                transaction.Commit();
50
            }
51
        }
52
 
53
        public void Remove(TEntity entity) 
54
        {
55
            using (ITransaction transaction = this.CurrentSession.BeginTransaction())
56
            {
57
                this.CurrentSession.Delete(entity);
58
                transaction.Commit();
59
            }
60
        }
61
    }
62
}

We are finished with the refactoring, so our attention shifts to building unit tests for our framework. As you noticed, we have no concrete classes – this is by design. So…how do we test interface and abstract classes? Why are we creating interfaces again?

The answer to question 2 is loose coupling and ability to test classes in isolation. This also promotes our core design principles and the supporting design patterns, which we covered in the “How to design and build better software for tomorrow?” series.

How do we test interface and abstract classes? The best approach is creating mock objects that implement the interfaces and inherit the base classes. The mock objects will mimic our concrete implementations, but with no real business logic. The following is the Framework Test project structure, which will contain our unit test and mock classes. 

The following is the EntityMock class, which inherits the EntityBase and defines the Generic type as int. This will represent the Id property type.

01
using System;
02
using Joemwalton.Framework.Domain;
03
 
04
namespace Joemwalton.Framework.Test.Mocks
05
{
06
    public class EntityMock 
07
        : EntityBase<int>
08
    {
09
        public EntityMock() 
10
        {
11
            this.Id = 1;
12
            Validate();
13
        }
14
 
15
        protected override void Validate()
16
        {
17
            this.FailedValidations.Clear();
18
            if (this.Id == 1)
19
                FailedValidations.Add("Testing");
20
        }
21
    }
22
}

The mock object contains an implementation for the constructor and Validate method, since the EntityBase handled the Id property. The following is the RepositoryMock class, which will focus on the relevant method implementation to support the framework.

01
using System;
02
using System.Collections.Generic;
03
using Joemwalton.Framework.Data.Repository;
04
using Joemwalton.Framework.Test.Mocks;
05
 
06
namespace Joemwalton.Framework.Test.Mocks
07
{
08
    public class RepositoryMock 
09
        : IRepository<EntityMock, int>
10
    {
11
        public void Save(EntityMock entity)
12
        {
13
            throw new NotImplementedException();
14
        }
15
 
16
        public void Remove(EntityMock entity)
17
        {
18
            throw new NotImplementedException();
19
        }
20
 
21
        public EntityMock FindById(int id)
22
        {
23
            return new EntityMock();
24
        }
25
 
26
        public List<EntityMock> FindAll()
27
        {
28
            return new List<EntityMock> { new EntityMock() };
29
        }
30
    }
31
}

The mock object implements the IRepository interface, where the contract defines the basic CRUD operations. The method implementation is not important, since we are not testing the ability of the Repository to retrieve or persist objects. The IRepository is a Generic interface, so the concrete entity type definition is required.

With the mock objects available, we can build our unit tests for the entity and Repository framework. In the following, the unit tests are based on the Microsoft Visual Studio Test libraries, although you can also build your tests with the open source NUnit framework. In either case, the goal is building the necessary unit tests for the framework.

01
using System;
02
using Microsoft.VisualStudio.TestTools.UnitTesting;
03
using Joemwalton.Framework.Data.Repository;
04
using Joemwalton.Framework.Test.Mocks; 
05
 
06
namespace Framework.Test
07
{
08
    [TestClass]
09
    public class EntityTest
10
    {
11
        public EntityTest() { }
12
 
13
        public TestContext TestContext { get; set; }
14
 
15
        [TestMethod]
16
        public void GetIdTest()
17
        {
18
            EntityMock mock = new EntityMock();
19
            int expected = 1;
20
            Assert.AreEqual(expected, mock.Id);
21
        }
22
 
23
        [TestMethod]
24
        public void SetIdTest()
25
        {
26
            EntityMock mock = new EntityMock();
27
            int expected = 2;
28
            mock.Id = expected;
29
            Assert.AreEqual(expected, mock.Id);
30
        }
31
 
32
        [TestMethod]
33
        public void GetFailedValidationsTest()
34
        {
35
            EntityMock mock = new EntityMock();
36
            Assert.AreEqual(1, mock.GetFailedValidations().Count);
37
            string expected = "Testing";
38
            Assert.AreEqual(expected, mock.GetFailedValidations()[0]);
39
        }
40
    }
41
}

In the above EntityTest class, we decorate the class with TestClass and test methods with TestMethod attributes. The test methods create an instance of the EntityMock and validate the results, although the EntityMock instantiation can also be accomplished during the test class initialization and shared for all test methods. The following is the RepositoryTest, which follows the same approach as the EntityTest.

01
using System;
02
using System.Text;
03
using System.Collections.Generic;
04
using System.Linq;
05
using Microsoft.VisualStudio.TestTools.UnitTesting;
06
using Joemwalton.Framework.Test.Mocks;
07
 
08
namespace Joemwalton.Framework.Test
09
{
10
    [TestClass]
11
    public class RepositoryTest
12
    {
13
        public RepositoryTest() { }
14
 
15
        public TestContext TestContext { get; set; }
16
 
17
        [TestMethod]
18
        [ExpectedException(typeof(NotImplementedException))]
19
        public void SaveTest()
20
        {
21
            RepositoryMock mock = new RepositoryMock();
22
            mock.Save(new EntityMock());
23
        }
24
 
25
        [TestMethod]
26
        [ExpectedException(typeof(NotImplementedException))]
27
        public void RemoveTest()
28
        {
29
            RepositoryMock mock = new RepositoryMock();
30
            mock.Remove(new EntityMock());
31
        }
32
 
33
        [TestMethod]
34
        public void FindByIdTest()
35
        {
36
            RepositoryMock mock = new RepositoryMock();
37
            EntityMock expected = new EntityMock();
38
            EntityMock actual = mock.FindById(1);
39
            Assert.AreEqual(expected.Id, actual.Id);
40
        }
41
 
42
        [TestMethod]
43
        public void FindAllTest()
44
        {
45
            RepositoryMock mock = new RepositoryMock();
46
            EntityMock expected = new EntityMock();
47
            List<EntityMock> actual = mock.FindAll();
48
            Assert.AreEqual(1, actual.Count);
49
            Assert.AreEqual(expected.Id, actual[0].Id);
50
        }
51
    }
52
}

The next step is run the tests. This is simple using Visual Studio, which includes several convenient options depending on your version. The Test menu or toolbar will provide an option to “Run All Tests in Solution”, which will run the tests and report the results. Alternatively, the Test View window will provide another interface to run tests.

In the Test View, you can highlight all tests and select “Run Selection” from the toolbar. This will execute the unit tests and display the information in the Test Results window, which appears below.

As you can see, the Test View window also provides several options to run and debug tests. Unfortunately, you will lose these handy features with an open source or non-Microsoft test tool.

In summary, we created mock objects for our domain model and Repository framework. Once we developed the mock objects, we created unit tests to ensure the relevant base implementation is working as expected. As we refactor the framework, the unit tests will ensure changes do not introduce bugs or break existing features. The introduction of a Continuous Integration (CI) process will further extend the test value with an event-driven build and test execution process. This can be accomplished using Microsoft Team Foundation Server (TFS), CruiseControl.NET, Team City or several other CI products.

What’s next? The next installment will focus on NHibernate including the SessionFactory, mapping and transaction management. This will segue into the IoC and Spring.NET support, which will provide many time saving NHibernate features.

Finally, I received several requests for a Java implementation. So…I am planning to build a Java equivalent enterprise framework solution. Thanks again for your comments and suggestions!!!!

Previous: Building Enterprise Frameworks – Data and Domain

Thinking Enterprise Architecture

Building Enterprise Frameworks – Data and Domain

0

In the previous blog entry “Thinking Enterprise Architecture”, I presented the background for a series focusing on Enterprise Architecture. Previously, we discussed the core design principles for software development. We also introduced several design patterns to satisfy the core principles. The concepts were applied to several technologies and demonstrated using Inversion of Control (IoC), Model-View-Controller (MVC) and Windows Communication Foundation (WCF). Since the core design principles and design patterns are not framework or language specific, the “Part VI: Brick Design – How to design and build better software for tomorrow?” article was a Java implementation of the Contact Manager application.

In this entry, I will provide the preliminary enterprise framework core components supporting the domain model and data tier. I will emphasize the word preliminary, because the framework will evolve and refactoring will be required to satisfy our objectives. I will loosely base the framework on the design built by the team introduced in the background entry, since they prefer not to share all design and implementations. The project will be based on my standard Contact Manager application. Basically, we are separating the common components and establishing a framework to build enterprise applications.

First, we create a new project as a class library for the common enterprise framework. The project contains the Data and Model root folders, which are collections of interface and abstract classes. These are not our concrete implementations, but the shared objects that our enterprise projects reference.

The Domain folder includes the IEntity interface and the abstract EntityBase class. All domain model concrete classes should implement IEntity. The interface is our contract, so this should drive the implementations within an interface-based system. The interface includes the Id property, which is the only domain object property that should be common for all concrete implementations.

1
using System;
2
 
3
namespace Joemwalton.Framework.Domain
4
{
5
    public interface IEntity<TId>
6
    {
7
        TId Id { get; set; }
8
    }
9
}

We elected to create a Generic interface, so we can define the types at run-time and not design-time. In this case, our Id property type is unknown. The implementation will define the type, so we are not forced to commit in the contract.

The EntityBase is an abstract class, which serves as a base class to define shared behavior for an implementation to inherit. This class is providing the implementation for the common entity Id property and validation logic. In this domain-driven design, we are encapsulating the business rules for validating the domain object. The Validate method is abstract, since only the concrete implementation would be aware of the validation logic required for the domain object. As we refactor the framework classes, the following will change to reflect our technical design.

01
using System;
02
using System.Collections.Generic;
03
 
04
namespace Joemwalton.Framework.Domain
05
{
06
    public abstract class EntityBase<TEntity,TId> 
07
        : IEntity<TId>
08
        where TEntity : IEntity<TId>
09
    {
10
        public  TId Id { get; set; }
11
 
12
        private List<string> _failedValidations = new List<string>();
13
        protected List<string> FailedValidations 
14
        {
15
            get { return _failedValidations; } 
16
        }
17
 
18
        public List<string> GetFailedValidations()
19
        {
20
            _failedValidations.Clear();
21
            Validate();
22
            return _failedValidations;
23
        }
24
 
25
        protected abstract void Validate();
26
    }
27
}

The next step is the skeleton design for the data tier, which includes the data access tier or repository. The repository is a memory-based domain collection, which is responsible for persisting and retrieving the domain objects. We will also build an interface and base class to support the concrete repository implementations. The IRepository interface is the contract, which includes methods for the standard Create-Read-Update-Delete (CRUD) operations. At this point, we would like all repository implementations to support the basic operations – Save, FindById, FindAll, Update and Delete. The concrete implemenations could include additional methods, which provide additional operations.

01
using System;
02
using System.Collections.Generic;
03
using Joemwalton.Framework.Domain;
04
 
05
namespace Joemwalton.Framework.Data.Repository
06
{
07
    public interface IRepository<TEntity,TId>
08
        where TEntity : IEntity<TId>
09
    {
10
        void Save(TEntity entity);
11
        void Remove(TEntity entity);
12
        TEntity FindById(TId id);
13
        List<TEntity> FindAll();
14
    }
15
}

Since our domain object type is unknown at design-time, we use generics to allow run-time assignments. The where clause is included as a contraint, so the run-time type must be IEntity. The TEntity represents the run-time domain object. The following RepositoryBase abstract class is a placeholder, so this will also be refactored as our design evolves.

01
using System;
02
using System.Collections.Generic;
03
using NHibernate;
04
using Joemwalton.Framework.Domain;
05
 
06
namespace Joemwalton.Framework.Data.Repository
07
{
08
    public abstract class BaseRepository<TEntity,TId> 
09
        : IRepository<TEntity,TId>
10
        where TEntity : IEntity<TId>
11
    {
12
        public void Remove(TEntity entity) { }
13
 
14
        public void Save(TEntity entity) { }
15
 
16
        public TEntity FindById(TId id)
17
        {
18
            return default(TEntity);
19
        }
20
 
21
        public List<TEntity> FindAll()
22
        {
23
            return new List<TEntity>() { default(TEntity) };
24
        }
25
    }
26
}

Next, the Data.NHibernate folder contains the NHibernateRepositoryBase abstract class. This class contains NHibernate implementation code including the SessionFactory. Since we also selected Spring.NET, the Spring framework Object-Relational Mapping (ORM) modules provides the plumbing for this support. The IoC container provides the features to simplify the configuration, NHibernate session and enterprise transaction management. This class will also require refactoring as the features and implementations are discovered, but the following is a start.

01
using System;
02
using NHibernate;
03
using Joemwalton.Framework.Data.Repository;
04
using Joemwalton.Framework.Domain;
05
 
06
namespace Joemwalton.Framework.Data.NHibernate
07
{
08
    public abstract class NHibernateRepositoryBase<TEntity,TId> 
09
        : BaseRepository<TEntity,TId>
10
        where TEntity : IEntity<TId>
11
    {
12
        private ISessionFactory sessionFactory;
13
 
14
        /// <summary>
15
        /// Session factory
16
        /// </summary>
17
        public ISessionFactory SessionFactory
18
        {
19
            protected get { return sessionFactory; }
20
            set { sessionFactory = value; }
21
        }
22
 
23
        /// <summary>
24
        /// Get current active session
25
        /// </summary>
26
        protected ISession CurrentSession
27
        {
28
            get { return sessionFactory.GetCurrentSession(); }
29
        }
30
    }
31
}

In summary, the above are the draft enterprise framework classes and refactoring will be required in the future installments of the series. In the next entry, we will build tests including the mock objects for our abstractions. Once the enterprise framework is established, we will create a Contact Manager application. So…stay tuned for the next article in this series!

Next: Building Enterprise Frameworks - Testing and Mock Objects

Previous: Thinking Enterprise Architecture

WCF and Spring.NET

0

In this article, we will demonstrate a WCF implementation using Spring.NET. This will enable us to utilize the IoC container features supporting Dependency Injection, so we can inject the dependencies required to instantiate and initialize the service.

In previous articles, we built POCO (Plain Old CLR Object) services to represent the business tier and slightly more complex objects for the data tier. This is still the recommended architecture for enterprise services when integration and interoperability are not required. A distributed/service oriented design will add overhead and require additional resources to support. If you intend to publish your services for external partners or integrate legacy systems then WCF is a great solution. 

I still recommend separation and building POCO services as discussed under previous articles. A POCO service is far more reusable than a highly decorated and framework dependent object. We can leverage WCF to expose the services to a variety of consumer applications without the burden of building all the plumbing. The following are some common WCF terms.

  • Endpoints – a network resource accessible by clients to communicate based on agreed contracts.
  • Bindings – the how to communicate with the endpoint. The lowest level is the transport to exchange messages over the network. The built-in transports include HTTP, TCP, Names Pipes and MSMQ. The parent levels include security and transactions.
  • Contracts – the contracts define the features exposed by the endpoint, which includes the message/data format and operations.
Contracts

The first step is create the service contract, which defines the service operations. The simplest approach is mark your service interface class with the ServiceContract attribute and the operation methods with the OperationContract attribute. In the example below, we decorated the IContactsService class with the appropriate attributes for a service contract.

01
using Joemwalton.ContactManager.Common.Model;
02
namespace Joemwalton.ContactManager.Common.Services
03
{
04
    [ServiceContract]
05
    public interface IContactsService
06
    {
07
        [OperationContract]
08
        void DeleteContact(int id);
09
        [OperationContract]
10
        Contact GetContact(int id);
11
        [OperationContract]
12
        IList<Contact> GetContacts();
13
        [OperationContract]
14
        int SaveContact(Contact contact);
15
    }
16
}

The above class will expose the DeleteContact, GetContact, GetContacts and SaveContact operations. The next step is defining the Data Contracts. The DataContract attribute will mark the classes that represent the message/data format for the operations. The Data Contract will instruct the framework to represent the marked items as an XSD, which is included in the WSDL exposed for consumers discovery. The DataMember attribute identifies the included class members.

Alternatively, types marked with the Serializable attribute and members not marked with NonSerialized will be serialized. The default DataContactSerializer will also serialize types and generate the WSDL for all CLR primitives (e.g. int32, string), arrays, collections and enumerations. Please see the Microsoft documentation for additional types supported by the serializer. In our example, we will add Serializable to the Contact class and leverage the supported primitives.

01
namespace Joemwalton.ContactManager.Common.Model
02
{
03
    [Serializable]
04
    public abstract class ModelBase
05
    {
06
        public virtual bool IsValid
07
        {
08
            get { return true; }
09
        }
10
    }
11
}
12
 
13
namespace Joemwalton.ContactManager.Common.Model
14
{
15
    /// <summary>
16
    /// Contact domain object
17
    /// </summary>
18
    ///
19
    [Table(Name="Contacts")]
20
    public class Contact : ModelBase
21
    {
22
 
23
        public Contact() { }
24
 
25
        public Contact(string name,
26
                       string emailAddress,
27
                       string mobilePhone)
28
        {
29
            Name = name;
30
            EmailAddress = emailAddress;
31
            MobilePhone = mobilePhone;
32
        }
33
 
34
        public Contact(int id,
35
                       string name,
36
                       string emailAddress,
37
                       string mobilePhone)
38
        {
39
            Id = id;
40
            Name = name;
41
            EmailAddress = emailAddress;
42
            MobilePhone = mobilePhone;
43
        }
44
 
45
        public Contact(int id,
46
                       string name,
47
                       string emailAddress,
48
                       string mobilePhone,
49
                       byte[] picture)
50
        {
51
            Id = id;
52
            Name = name;
53
            EmailAddress = emailAddress;
54
            MobilePhone = mobilePhone;
55
            Picture = picture;
56
        }
57
 
58
        private int _Id = -1;
59
        public int Id 
60
        {
61
            get { return _Id; }
62
            set { _Id = value; }
63
        }
64
 
65
        public string Name { get; set; }
66
 
67
        public string EmailAddress { get; set; }
68
 
69
        public string MobilePhone { get; set; }
70
 
71
        public byte[] Picture { get; set; }
72
 
73
        public override bool IsValid
74
        {
75
            get { return true; }
76
        }
77
     }
78
}
79

WCF Service

The next step is implementing the service, which as we discussed previously will be a wrapper exposing our concrete service. The following is the ContactsService concrete implementation, which is the same POCO service we are using for other enterprise applications.

01
using Joemwalton.ContactManager.Common.Model;
02
using Joemwalton.ContactManager.Common.Repository;
03
 
04
namespace Joemwalton.ContactManager.Common.Services
05
{
06
    public class ContactsService : IContactsService
07
    {
08
        private IContactRepository _contactRepository;
09
        private INotificationService _notificationService;
10
 
11
        public ContactsService() { }
12
 
13
        //dependencies are now injected using the constructor
14
        public ContactsService(IContactRepository contactRepository,
15
                               INotificationService notificationService)
16
        {
17
            _contactRepository = contactRepository;
18
            _notificationService = notificationService;
19
        }
20
 
21
        public int SaveContact(Contact contact)
22
        {
23
            //code is simple and easy to understand!
24
            int id = _contactRepository.Save(contact);
25
            _notificationService.Send(contact);
26
            return id;
27
        }
28
 
29
        public IList<Contact> GetContacts()
30
        {
31
            return _contactRepository.FindAllContacts();
32
        }
33
 
34
        public Contact GetContact(int id)
35
        {
36
            return _contactRepository.FindById(id);
37
        }
38
 
39
        public void DeleteContact(int id)
40
        {
41
            _contactRepository.Remove(id);
42
        }
43
    }
44
}
45

First, add a new WCF Service to your project. You have an option to create a WCF service written in code or configuration. We will select the configuration option, which requires the addition of the ServiceModel configuration section. This will configure the endpoint including the address, binding and contract. The following is the web.config configuration section.

01
  <system.serviceModel>
02
      <services>
03
        <service name="ContactsService"
04
                 behaviorConfiguration="defaultBehavior">
05
          <host>
06
            <baseAddresses>
07
              <add baseAddress="http://localhost/ContactManager"/>
08
            </baseAddresses>            
09
          </host>
10
          <endpoint address=""
11
                    binding="basicHttpBinding"
12
                    contract="Joemwalton.ContactManager.Common.Services.IContactsService"/>
13
          <endpoint address="mex"
14
                    binding="mexHttpBinding"
15
                    contract="IMetadataExchange"/>
16
        </service>
17
      </services>  
18
      <behaviors>
19
            <serviceBehaviors>
20
                <behavior name="defaultBehavior">
21
                    <serviceMetadata httpGetEnabled="true" />
22
                    <serviceDebug includeExceptionDetailInFaults="true" />
23
                </behavior>
24
            </serviceBehaviors>
25
        </behaviors>
26
     <serviceHostingEnvironment multipleSiteBindingsEnabled="true"/>
27
  </system.serviceModel>
28

The above ContactsService service configuration defines 2 endpoints. The first is the basicHttpBinding referencing our Joemwalton.ContactManager.Common.Services.IContactsService contract, which defines the service operations. This is not the concrete implementation, so this we will address in the next section. The basicHttpBinding is compatible with ASMX. The second is the MEX endpoint, which provides the meta-data information describing the service to consumers. The MEX endpoint is not exposed by default, so you can add this configuration. As you can see, we can add multiple service endpoints to provide the flexibility to communicate with a variety of consumers.

Since we selected a configuration-based WCF client, the svc file will be essentially empty (i.e. no code-behind for the service implementation). The following is the svc file, which you can edit the markup to include Spring.NET WCF configuration.

1
<%@ ServiceHost Language="C#" 
2
                Debug="true"
3
                Service="ContactsService"
4
                Factory="Spring.ServiceModel.Activation.ServiceHostFactory" %>

The 2 key attributes are Service and Factory. The Service attribute is the IoC object name of the concrete ContactsService implementation. The Factory attribute is set to the Spring.NET ServiceHostFactory, which provides the IoC Dependency Injection features. In this scenario, the factory will request an instance of the ContactsService object from the Spring.NET IoC container. You must set the Service attribute and IoC object name/id to the same value, which is necessary for the container to locate the correct object.

The next step is providing the instructions to the IoC container for wiring the objects, so the ServiceHostFactory returns the ContactsService object already initialized with all dependencies injected. In this case, the IContactRepository and INotificationService objects. The following is the XML meta-data defining the object for the IoC container.

01
<?xml version="1.0" encoding="utf-8" ?>
02
  <objects xmlns="http://www.springframework.net">
03
 
04
    <object id="EmailNotificationService"
05
            type="Joemwalton.ContactManager.Common.Services.EmailService, Joemwalton.ContactManager.Common">
06
      <constructor-arg name="smtpHost"  value="${Smtp.Host}" />
07
      <constructor-arg name="sender"    value="${Email.Sender}" />
08
      <constructor-arg name="subject"   value="Hello!" />
09
      <constructor-arg name="message"   value="Hello Email Contact!" />
10
    </object>
11
 
12
    <object id="ContactsService"
13
            type="Joemwalton.ContactManager.Common.Services.ContactsService, Joemwalton.ContactManager.Common"
14
            singleton="false">
15
      <constructor-arg name="contactRepository">
16
        <object type="Joemwalton.ContactManager.Common.Repository.SqlContactRepository, Joemwalton.ContactManager.Common" />
17
      </constructor-arg>
18
      <constructor-arg name="notificationService"
19
                       ref="EmailNotificationService" />
20
    </object>
21
  </objects>
22

The ServiceHostFactory will request the ContactsService object from IoC container by name/id. The container will instantiate the object based on the XML meta-data above, which references the type as ContactsService. The constructor is provided an instance of the SqlContactRepository and EmailNotificationService reference. The second constructor argument is a reference to another object, which is also defined in the XML meta-data as EmailNotificationService. If you are reading this post before the article describing the design patterns then I recommend reviewing the previous series for additional information.

Hosting

We basically built our WCF service and leveraged the Spring.NET IoC container to instantiate the service using WCF Service Host extensibility. Since we are exposing HTTP endpoint bindings, we will select IIS as the service host environment. The ContactManager.Soa.Server project, which will host our service under IIS. The web project will include the svc, XML meta-data and web.config. We will configure the web project to create a virtual directory and host under local IIS, so we can call the service locally for testing.

This configuration will allow us to access the service using the Project URL and service name. The following browser image represents the result when calling the service.

You can view the WSDL by clicking the link, which returns the following. As discussed previously, the WSDL provides the instructions for consumers to properly interact with your service.

Summary

In summary, we created a WCF service as a wrapper to an existing service. The POCO service is a concrete implementation containing the business logic to fulfill the request and respond appropriately. In our example, the service will call the Repository to persist data and a notification service to send email messages. We can still call the POCO service directly within the enterprise, but WCF offers a distributed architecture with options to communicate with external clients. Since we followed our core design patterns and principles, we introduced Spring.NET to provide an IoC container to instantiate and initialize our service. We are able to preserve all the design benefits of our non-distributed enterprise applications.

The following are a few additional items to consider.

  • The example is a standard synchronous request-response pattern with the client blocked, so consider an asynchronous request-response pattern for longer running service operations. One-way and duplex are also options.
  • Although HTTP is the most popular transport protocol, consider TCP and Named Pipes for a .NET only environment. The TCP and Named Pipes provide a performance boost over HTTP. 
  • IIS6 is a great hosting environment for HTTP based service endpoints, although Windows Process Activation Services (WAS)/II7 and a Managed Windows Service provide support for non-HTTP protocols.
  • Expose multiple endpoints to support legacy and non-.NET consumers (i.e. Java).
  • WCF provides many bindings including Web Services based on WS-I Basic Profile 1.1 (i.e. SOAP 1.1, WSDL 1.1) and the more advanced WS-* specifications.
  • Text encoding is standard, but binary and MTOM are options to reduce the payload and improve performance. You can define the encoding in the bindings. Check binding encoding restrictions.
  • Don’t forget about security for sensitive and confidential data!!! Transport and Message-based security are supported. The transport deals with protecting data over the wire, where SSL is the most common. Client Authentication is available with Windows credentials, certificates, SAML tokens and user/password secret.
  • Set the service XML meta-data object singleton attribute to false, so the IoC container creates a new instance.
  • Refer to the source code download for additional configuration and settings required for this solution not covered in the article.
Source Code

The source code for the solution contains several projects, which provide various scenarios and examples. The following is a brief summary of the projects.

  • ContactManager.Common – includes domain objects, repository and POCO services. The SqlContactRepository, LinqContactRepository and MemoryContactRepository are three Contact Repository concrete implementations. 
  • ContactManager.Soa.Server – includes the WCF service host with Spring.NET IoC support.
  • ContactManager.Soa.Client – includes the WCF service client.
  • ContactManager.Web – an MVC version of the Contact Manager UI with Spring.NET IoC support, which is currently setup to call the ContactManager.Common ContactsService POCO service. The ContactsService is currently configured to call the SqlContactRepository.
  • ContactManager.WinForm – a WinForm version of the Contact Manager UI, which is currently setup to call the ContactManager.Soa.Client. The ContactManager.Soa.Server is configured to call the LinqContactRepository using Spring.NET. 

You can download the source code and setup a local SQL Server database using the create scripts in the sql folder. You can also easily modify the Contact Repository implementation via the IoC container XML meta-data. The MemoryContactRepository is available for testing when you do not have a persistent data store available (e.g. SQL Server).

What’s Next?

I will follow-up with part 2 to discuss the service client setup and configuration, which does not require any external libraries or processes. The service host will handle the business and data tier, so the service client is a standard implementation.

I am also planning a Windows Workflow Foundation (WF) article as an alternative implementation for the business tier. In our example, the ContactsService method calls the Repository and NotificationService objects to fulfill the business requirement. We will replace this implementation with a workflow encapsulating this process and inject business rules into the workflow, which will also be exposed as a WCF service. If you have worked with Team Foundation Server (TFS) builds then you will be familiar with workflows.

I hope this article provides a WCF implementation, which follows the design patterns and principles for enterprise systems.

Source Code

Part VII: ASP.NET MVC Contact Manager with Spring.NET

2

This series is an adaption of my “Getting Started with Dependency Injection using Spring.NET” presentation, which was a session available at the Orlando .NET Code Camp 2012. Since I received invaluable participation and feedback from the attendees, this post will include expanded material and code examples.

This should be the final part of the series, which is the missing ASP.NET MVC example from the Orlando .NET Code Camp presentation. I received several requests to provide the ASP.NET MVC examples, since time expired before I was able to demonstrate during the presentation. I am including the Stick Contact Manager and Brick Contact Manager ASP.NET MVC versions, so you can download the source code. As discussed previously, the examples are primarily to provide the foundation for the design patterns and principles – not a full blown ASP.NET MVC web application with all the bells and whistles.

ASP.NET MVC is the perfect web architecture to promote our design patterns and principles we established throughout this series. The ASP.NET Web Forms paradigm is showing some age and not able to keep pace with evolving web technologies and increasing demands on applications. The Model-View-Controller design pattern is not page-centric like Web Forms, but instead is based on actions. The overall theme is separation, where the layers are maintainable, testable with a single responsibility. This sounds like everything we discussed, so let’s get started.

In Part IV, we refactored our prototype design and introduced the Stick Contact Manager. We applied several design patterns, which established a solid foundation for well-designed software. The design patterns and principles include Dependency Injection Principle (DIP), Separation of Concerns (SoC), Dependency Injection (DI) and Single Responsibility Principle (SRP). The Stick Contact Manager scored high marks during our evaluation, although we discovered one frustrating side-effect of the design – the client still must have knowledge of how to create the dependencies. We successfully eliminated the dependency creation throughout the majority of the objects, but we are forced to write significant code to create the dependencies.

The solution is centralizing the object creation or instantiation, so the client can delegate the task and knowledge of all the dependencies to another entity. This can also promote reusability, so the clients or consumers can also delegate this task to the same entity. This would eliminate the need for redundant client code required to create the dependencies.

So…let’s review the Stick Contact Manager MVC. Since we applied the Dependency Injection pattern, the dependencies are injected via the constructor. The core of MVC is the controller, which is responsible for processing the request and orchestrating the workflow to generate the appropriate response.

01
        private ContactsService _service;
02
        private ContactManager.Common.Repository.IContactRepository _repository;
03
        private ContactManager.Common.Services.INotificationService _notification;
04
 
05
        public ContactController() 
06
        {
07
            _repository = new ContactManager.Common.Repository.ContactRepository();
08
            _notification = new EmailService("myHost",
09
                                             "no-reply@test.com",
10
                                             "TEST", "Test Message");
11
            _service = new ContactsService(_repository,
12
                                           _notification,
13
                                           _notification);
14
        }
15

As discussed previously, the above Stick Contact Manager controller still must have knowledge of how to create the dependencies. As an alternative, we will introduce Inversion of Control (IoC) for our centralized object creation solution. An IoC container will handle the object creation, so now we can remove the majority of the instantiation code. In general, IoC inverts the relationship by the client delegating control to the container.

Let’s refactor the ContactController, so the Spring.NET IoC container will instantiate the object and inject all dependencies.

1
   public class ContactController : Controller
2
    {
3
        private ContactsService _service;
4
 
5
        public ContactController(ContactsService service)
6
        {
7
            _service = service;
8
        }

We significantly reduced the clutter regarding the instantiation of the objects, which has been delegated to the Spring.NET IoC container. How are we using Spring.NET IoC, because we do not see the code like the console application? This will require a small addition to the web.config, which allows the container to manage the instantiation and initialization of the participating objects. The following is the web.config entry to accomplish this task.

1
  <configSections>
2
    <sectionGroup name="spring">
3
      <section name="context" type="Spring.Context.Support.MvcContextHandler, Spring.Web.Mvc"/>
4
    </sectionGroup>
5
  </configSections>

How does the container know how to create the objects? Well, we will need to provide the instructions to the container. We will select the xml metadata configuration approach, so the object definition is contained in an external xml file. So…let’s look at the object definitions in the xml metadata files.

01
  <object type="MvcContactManager.Controllers.ContactController, MvcContactManager"
02
          singleton="false" >
03
    <constructor-arg ref="ContactsService"/>
04
  </object>
05
 
06
  <object id="ContactsService"
07
        type="ContactManager.Common.Services.ContactsService, ContactManager.Common">
08
    <!-- inline object -->
09
    <constructor-arg name="contactRepository">
10
      <object type="ContactManager.Common.Repository.ContactRepository, ContactManager.Common" />
11
    </constructor-arg>
12
    <constructor-arg name="helloNotificationService"    ref="HelloEmailNotificationService" />
13
    <constructor-arg name="goodbyeNotificationService"  ref="GoodbyeEmailNotificationService" />
14
  </object>
15
 
16
  <object id="HelloEmailNotificationService"
17
        type="ContactManager.Common.Services.EmailService, ContactManager.Common">
18
    <constructor-arg name="smtpHost"  value="${Smtp.Host}" />
19
    <constructor-arg name="sender"    value="${Email.Sender}" />
20
    <constructor-arg name="subject"   value="Hello!" />
21
    <constructor-arg name="message"   value="Hello Email Contact!" />
22
  </object>
23
 
24
  <!-- setter-based injection with abstract parent -->
25
  <object id="GoodbyeEmailNotificationService"
26
          type="ContactManager.Common.Services.EmailService, ContactManager.Common"
27
          parent="MailBase">
28
    <property name="Subject"  value="Hello!" />
29
    <property name="Message"  value="Hello Email Contact!" />
30
  </object>
31

We have 2 additional object definitions, so we can assign properties from external sources. In this case, we would like the web.config appSettings to be accessible to the objects. In the example above, the ${Smtp.Host} placeholder is replaced with the corresponding configuration appsettings value. The MailBase object contains the shared property values, which can be referenced using the parent attribute.

01
 <object type="Spring.Objects.Factory.Config.VariablePlaceholderConfigurer, Spring.Core">
02
    <property name="VariableSources">
03
      <list>
04
        <object type="Spring.Objects.Factory.Config.ConfigSectionVariableSource, Spring.Core">
05
          <property name="SectionName" value="appSettings" />
06
        </object>
07
      </list>
08
    </property>
09
  </object>
10
 
11
  <object id="MailBase">
12
    <property name="SmtpHost" value="${Smtp.Host}" />
13
    <property name="Sender"   value="${Email.Sender}" />
14
  </object>

The element object contains the instructions to instantiate and initialize an object. The id or name attribute is the  reference name, which is the value that is passed when requesting an object from the IoC container. The type attribute is the namespace qualified class name and fully qualified assembly name. The primary object child elements include the constructor-arg and property, which provide constructor and setter based dependency injection techniques. There are several options to the constructor element, which include name and index attributes. The container will attempt to match the signature of the appropriate constructor, so providing the correct name or index of the parameters is important. The value attribute is the static value, expression or placeholder. In the example above, the ${Smtp.Host} value is replaced with the configuration appsettings value. The ref attribute identifies the name or id of another object element, so the value is set to this object.

Please refer to Part V or presentation for additional information regarding the xml metadata.

The remaining component of Spring MVC is the application routing, which requires some plumbing code to complete. The following is the Stick Contact Manager global.asax file with the traditional implementation required for registering the routes.

01
using System;
02
using System.Web;
03
using System.Web.Mvc;
04
using System.Web.Routing;
05
 
06
namespace MvcContactManager
07
{
08
    public class MvcApplication : System.Web.HttpApplication
09
    {
10
        public static void RegisterGlobalFilters(GlobalFilterCollection filters)
11
        {
12
            filters.Add(new HandleErrorAttribute());
13
        }
14
 
15
        public static void RegisterRoutes(RouteCollection routes)
16
        {
17
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
18
 
19
            routes.MapRoute(
20
                "Default", // Route name
21
                "{controller}/{action}/{id}", // URL with parameters
22
                new { controller = "Home",
23
                      action = "Index",
24
                      id = UrlParameter.Optional } // Parameter defaults
25
            );
26
        }
27
 
28
        protected void Application_Start()
29
        {
30
            AreaRegistration.RegisterAllAreas();
31
 
32
            RegisterGlobalFilters(GlobalFilters.Filters);
33
            RegisterRoutes(RouteTable.Routes);
34
        }
35
    }
36
}

This is a lot of redundant code and hard-coded route registration process, which could be cumbersome with more complex implementations. The Spring MVC approach is much simpler and requires no additional coding to define the application routing.

01
using System.Web;
02
using System.Web.Mvc;
03
using System.Web.Routing;
04
using Spring.Web.Mvc;
05
using Spring.Context.Support;
06
 
07
namespace MvcContactManager
08
{
09
    public class MvcApplication : SpringMvcApplication
10
    {
11
 
12
    }
13
}

The routing is mapped to the appropriate controller, where the action invoker matches the public method. The action method of the controller handles the HTTP POST, which will call the ContactsService to process the request. The console application follows the same process, which collects the input from the client and calls ContactsService. The following is the ContactController, which handles the Add action and like the console Contact Manager will delegate the responsibility to the ContactsService. The controller is not concerned with what is required to add a contact.

01
using System;
02
using System.Web;
03
using System.Web.Mvc;
04
using ContactManager.Common.Services;
05
using MvcContactManager.ViewModels;
06
using ContactManager.Common.Model;
07
 
08
namespace MvcContactManager.Controllers
09
{
10
    public class ContactController : Controller
11
    {
12
        private ContactsService _service;
13
 
14
        public ContactController(ContactsService service)
15
        {
16
            _service = service;
17
        }
18
 
19
        [HttpGet]
20
        public ActionResult Add()
21
        {
22
            var model = new ContactViewModel();
23
            return View(model);
24
        }
25
 
26
        [HttpPost]
27
        public ActionResult Add(ContactViewModel inputForm)
28
        {
29
            var model = new ContactViewModel(inputForm.Name,
30
                                             inputForm.Email,
31
                                             inputForm.Phone);
32
 
33
            //Check if model is valid and call service to add contact
34
            if (this.ModelState.IsValid)
35
            {
36
                _service.AddContact(new Contact(model.Name,
37
                                                model.Email,
38
                                                model.Phone));
39
            }
40
 
41
            return View(model);
42
        }
43
    }
44
}
45

The ContactViewModel is the model, which identifies the properties that will be available to the view. We also decorate the class with validation attributes, which will provide the input validation. We will also separate the view and domain models. The domain model will remain with the Contact Manager common library, where it represents the data managed by the data tier (i.e. database).

01
namespace MvcContactManager.ViewModels
02
{
03
    public class ContactViewModel 
04
    {
05
        public ContactViewModel()
06
            : this(string.Empty,
07
                  string.Empty,
08
                  string.Empty) { }
09
 
10
        public ContactViewModel(string name,
11
                                string email,
12
                                string phone)
13
        {
14
            this.Name = name;
15
            this.Email = email;
16
            this.Phone = phone;
17
        }
18
 
19
        [Required(ErrorMessage="Name is required.")]
20
        [StringLength(40, 
21
                      ErrorMessage="Name cannot be greater than 40.")]
22
        public string Name { get; set; }
23
 
24
        [Required(ErrorMessage = "Email is required.")]
25
        [RegularExpression(@"^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$",
26
                           ErrorMessage = "Email not valid format.")]
27
        public string Email { get; set; }
28
 
29
        [Required(ErrorMessage = "Phone is required.")]
30
        [RegularExpression(@"((\(\d{3}\) ?)|(\d{3}-))?\d{3}-\d{4}",
31
                           ErrorMessage = "Phone not valid format (###)###-#### or (###)###-####.")]
32
        public string Phone { get; set; }
33
    }
34
}

The following is the view, which will present our form to add contact information. The controller populated the model, which is available for the view to present dynamic data. The ViewBag and ViewData are also collections available for the view. NOTE: the ViewBag is available under ASP.NET MVC3 and .NET 4.

01
@model MvcContactManager.ViewModels.ContactViewModel
02
@{ ViewBag.Title = "Add Contact"; }
03
 
04
@using (Html.BeginForm("Add", "Contact", FormMethod.Post))
05
{
06
<div id="AddEditor">
07
    @Html.ValidationSummary("Please correct errors below and click Add again:")
08
    <fieldset>        
09
        <legend>Contact</legend>
10
        <table cellpadding="0" cellspacing="0">
11
            <tr>
12
                <td><span style="text-align: right;">Name</span></td>
13
                <td>@Html.TextBox("Name", @Model.Name)@Html.ValidationMessage("Name", "*")</td>
14
            </tr>
15
            <tr>
16
                <td><span style="text-align: right;">Email</span></td>
17
                <td>@Html.TextBox("Email", @Model.Email)@Html.ValidationMessage("Email", "*")</td>
18
            </tr>
19
            <tr>
20
                <td><span style="text-align: right;">Phone</span></td>
21
                <td>@Html.TextBox("Phone", @Model.Phone)@Html.ValidationMessage("Phone", "*")</td>
22
            </tr>
23
        </table>    
24
        <p><input type="submit" value="Add"/></p>    
25
    </fieldset>    
26
</div>                      
27
}

The following is a screenshot of the rendered page, which is after our initial postback and validation.

Brick Contact Manager MVC

The IoC alternatives including Service Locator and Factory Design patterns also provide solutions for centralizing the object creation. The Factory Design hides the complexities with a factory object that contains static methods returning the instantiated object. The Service Locator is also a central repository, which the client passes a key to retrieve an object. These options also work well with the core Dependency Injection Principle (DIP), Separation of Concern (SoC), Dependency Injection (DI) and Single Responsibility Principle (SRP). I always recommend exploring your options and pick the approach that works best for your project.

In summary, the Brick Contact Manager MVC solves the object creation responsibility problem. I have found that following the software design principles we have defined in Part II and implementing the patterns in Part IV are a good defense against premature end-of-life scenario for your applications. The addition of an IoC container will further promote the software design principles and add significant value to your product. You will find maintenance and change requests will be less painful.

I hope you found this series helpful and will be able to follow the concepts presented with your next project. We completed .NET and Java examples to illustrate the design patterns and practices can be applied to any OO language. We also built a console application and MVC client, which provides guidelines for integrating with the Spring IoC container. Please follow the below links to source code and related posts for additional information.

Source Code

Part V: Brick Contact Manager – Console Application

Previous: Part IV: Stick Contact Manager

Java Version: Part VI: Brick Contact Manager

Part VI: Java Brick Design – How to design and build better software for tomorrow?

0

Since the “How to design and build better software for tomorrow?” series, I received a few requests from members and colleagues in the Java community. Although the concepts and techniques can be applied to all OO languages, the code examples are C# .NET. Since the majority of my recent projects have been .NET, I just naturally start thinking and writing .NET. So…this post will be a port of the Brick Contact Manager .NET project to Java. If you did not follow the series then I encourage you to read the 4 previous entries as background. If you found this post and prefer the .NET flavor then click here.

In Part IV, we refactored our prototype design and introduced the Stick Contact Manager. We applied several design patterns, which established a solid foundation for well-designed software. The design patterns and principles include Dependency Injection Principle (DIP), Separation of Concerns (SoC), Dependency Injection (DI) and Single Responsibility Principle (SRP).

The following are the classes of the common library, which are referenced by the Brick Contact Manager console application. They have been refactored to follow the above design patterns, which were discussed in the previous entries of the series.

The Contact class is a POJO representing the model or domain object for our contact information. The IContactRepository is the interface or contract for our implementation of the data layer responsible for persistence of the contact information. The ContactRepository represents our concrete implementation.

01
package contactmanager.common.model;
02
 
03
import java.io.Serializable;
04
 
05
/**
06
 * Domain Object
07
 *
08
 */
09
public class Contact implements Serializable {
10
 
11
    private Integer id;
12
    private String name;
13
    private String emailAddress;
14
    private String mobilePhone;
15
 
16
    public Contact() {
17
    }
18
 
19
    public Contact (String Name,
20
                    String EmailAddress,
21
                    String MobilePhone) {
22
        this.name = Name;
23
        this.emailAddress = EmailAddress;
24
        this.mobilePhone = MobilePhone;
25
    }
26
 
27
    public Integer getId() {
28
        return this.id;
29
    }
30
 
31
    public void setId(Integer Id) {
32
        this.id = Id;
33
    }
34
 
35
    public String getName() {
36
        return this.name;
37
    }
38
 
39
    public void setName(String Name) {
40
        this.name = Name;
41
    }
42
 
43
    public String getMobilePhone() {
44
        return this.mobilePhone;
45
    }
46
 
47
    public void setModilePhone(String MobilePhone) {
48
        this.mobilePhone = MobilePhone;
49
    }
50
 
51
    public String getEmailAddress() {
52
        return this.emailAddress;
53
    }
54
 
55
    public void setEmailAddress(String EmailAddress) {
56
        this.emailAddress = EmailAddress;
57
    }
58
 
59
    @Override
60
    public String toString()
61
    {
62
        return new StringBuilder()
63
                .append("Name=")
64
                .append(this.name)
65
                .append("\nEmailAddress=")
66
                .append(this.emailAddress)
67
                .append("\nMobilePhone=")
68
                .append(this.mobilePhone)
69
                .toString();
70
    }
71
}

01
package contactmanager.common.repository;
02
 
03
import contactmanager.common.model.Contact;
04
 
05
/**
06
 * ContactRepository contract
07
 * Create one or more implementations.
08
 */
09
public interface IContactRepository {
10
 
11
    void save(Contact contact);
12
}

01
package contactmanager.common.repository;
02
 
03
import contactmanager.common.model.Contact;
04
 
05
/**
06
 * Concrete implementation to persist contact to data store
07
 * I am now separated with a single responsibility to be maintainable,
08
 * reusable and testable!
09
 */
10
public class ContactRepository implements IContactRepository {
11
 
12
    public ContactRepository() { }
13
 
14
    @Override
15
    public void save(Contact Contact) {
16
        System.out.println("ContactRepository.Save: \n" +
17
                Contact.toString());
18
        //TODO: code to persist contact
19
    }
20
}

If we introduce a new technique to persist the contact information then building a new contact repository implementation would be simple. The design patterns will enable us to simplify the process of swapping the new contact repository implementation, so the enterprise application would require no coding changes. This technique is also beneficial for prototyping, so you are not forced to modify your high-level classes. You are creating classes that rely on abstractions or interfaces instead of concrete implementations, so you have the flexibility to swap implementations without significant impact – the ripple effect.

We apply the same technique for the notification services, where the INotificationService is the abstraction/interface and we can create any number of concrete implementations. In our example below, we built the EmailService to provide email capabilities. The same benefits apply as discussed previously, so we can create new concrete implementations for notification services without causing a ripple effect throughout the system. The change is less painful using the design patterns.

01
package contactmanager.common.services;
02
 
03
import contactmanager.common.model.Contact;
04
/**
05
 * NotificationService contract
06
 * Create one or more implementations. Try using an abstract
07
 * class if shared features are beneficial to the implementations.
08
 */
09
public interface INotificationService {
10
 
11
    void send(Contact Contact);
12
 
13
    String getMessage();
14
 
15
    void setMessage(String Message);    
16
}

001
002
/**
003
 * Concrete implementation to send email notifications
004
 * I am now separated with a single responsibility to be maintainable,
005
 * reusable and testable!
006
 */
007
public class EmailService implements INotificationService {
008
 
009
    private String message;
010
    private String subject;
011
    private String sender;
012
    private String smtpHost;
013
 
014
    public EmailService() { }
015
 
016
    public EmailService(String SmtpHost,
017
                        String Sender,
018
                        String Subject,
019
                        String Message) {
020
            this.message = Message;
021
            this.subject = Subject;
022
            this.sender = Sender;
023
            this.smtpHost = SmtpHost;
024
    }
025
 
026
    @Override
027
    public void send(Contact Contact)
028
    {
029
        System.out.println("EmailService.Send: \n" +
030
                toString() +
031
                Contact.getName());
032
        //TODO: email
033
    }
034
 
035
    @Override
036
    public String toString()
037
    {
038
        return new StringBuilder()
039
                .append("SmtpHost=")
040
                .append(this.smtpHost)
041
                .append("\nSender=")
042
                .append(this.sender)
043
                .append("\nSubject=")
044
                .append(this.subject)
045
                .append("\nMessage=")
046
                .append(this.message)
047
                .toString();
048
    }
049
 
050
    /**
051
     * @return the Message
052
     */
053
    @Override
054
    public String getMessage() {
055
        return this.message;
056
    }
057
 
058
    /**
059
     * @param Message the Message to set
060
     */
061
    @Override
062
    public void setMessage(String Message) {
063
        this.message = Message;
064
    }
065
 
066
    /**
067
     * @return the Subject
068
     */
069
    public String getSubject() {
070
        return this.subject;
071
    }
072
 
073
    /**
074
     * @param Subject the Subject to set
075
     */
076
    public void setSubject(String Subject) {
077
        this.subject = Subject;
078
    }
079
 
080
    /**
081
     * @return the Sender
082
     */
083
    public String getSender() {
084
        return this.sender;
085
    }
086
 
087
    /**
088
     * @param Sender the Sender to set
089
     */
090
    public void setSender(String Sender) {
091
        this.sender = Sender;
092
    }
093
 
094
    /**
095
     * @return the SmtpHost
096
     */
097
    public String getSmtpHost() {
098
        return this.smtpHost;
099
    }
100
 
101
    /**
102
     * @param SmtpHost the SmtpHost to set
103
     */
104
    public void setSmtpHost(String SmtpHost) {
105
        this.smtpHost = SmtpHost;
106
    }
107
}

The ContactsService class is our final common library object, which is the called by the Brick Contact Manager user interface to handle our business logic. It is responsible for orchestrating the objects required to perform complete the desired client request, which is add a contact in our example. We do not have logic to email or persist data, since these tasks have been delegated to the appropriate objects. The design is decoupled from the concrete implementations, since the constructors accept abstractions/interfaces instead of concrete types.

01
package contactmanager.common.services;
02
 
03
import contactmanager.common.model.Contact;
04
import contactmanager.common.repository.IContactRepository;
05
/**
06
 * High-level concrete contacts service - called by the client
07
 * I am not married to low-level concrete dependencies, so any
08
 * changes will no longer affect me. I now depend on interfaces
09
 * or abstract classes.
10
 */
11
public class ContactsService {
12
 
13
    private IContactRepository ContactRepository;
14
    private INotificationService NotificationService;
15
 
16
    //dependencies are now injected using the constructor
17
    public ContactsService(IContactRepository ContactRepository,
18
                           INotificationService NotificationService)
19
    {
20
        this.ContactRepository = ContactRepository;
21
        this.NotificationService = NotificationService;
22
    }
23
 
24
    public void addContact(Contact Contact)
25
    {
26
        //code is simple and easy to understand!
27
        System.out.println("ContactsService.AddContact: \n" +
28
                Contact.toString());
29
        this.ContactRepository.save(Contact);
30
        this.NotificationService.send(Contact);
31
    }
32
}

The Stick Contact Manager (see Part IV) scored high marks during our evaluation, although we discovered one frustrating side-effect of the design – the client still must have knowledge of how to create the dependencies. We successfully eliminated the dependency creation throughout the majority of the objects, but we are forced to write significant code to create the dependencies.

The solution is centralizing the object creation or instantiation, so the client can delegate the task and knowledge of all the dependencies to another entity. This can also promote reusability, so the clients or consumers can also delegate this task to the same entity. This would eliminate the need for redundant client code required to create the dependencies.

As discussed previously, the Stick Contact Manager client still must have knowledge of how to create the dependencies. As an alternative, we will introduce Inversion of Control (IoC) for our centralized object creation solution. An IoC container will handle the object creation, so now we can remove the majority of the code and just request the object. In general, IoC inverts the relationship by the client delegating control to the container. In this example, we selected Spring for the job.

So…let’s refactor the client for the Brick Contact Manager to call the Spring IoC container and request the ContactsService (download source code). The container will instantiate the object and injects all dependencies, so the object is ready to use without additional initialization.

01
package brickcontactmanager;
02
 
03
import contactmanager.common.model.Contact;
04
import contactmanager.common.services.ContactsService;
05
import org.springframework.context.ApplicationContext; 
06
import org.springframework.context.support.ClassPathXmlApplicationContext;
07
 
08
/** 
09
* Simple console application to illustrate the design patterns of ContactManager
10
*
11
*/
12
public class BrickContactManager {
13
 
14
    /**
15
     * @param args the command line arguments
16
     */
17
    public static void main(String[] args) {
18
        System.out.println("*** BrickContactManager ***");
19
        //set reference to IoC container
20
        ApplicationContext context = 
21
                new ClassPathXmlApplicationContext("applicationContext.xml",
22
                BrickContactManager.class);
23
        /* request object from container - client is no longer aware of how
24
           to construct the object and its' dependencies!!! */
25
        ContactsService service = (ContactsService)context.getBean( "ContactsService" );
26
 
27
        service.addContact(new Contact("John Doe",
28
                                       "jwalton@test.com",
29
                                       "0000000000"));
30
    }
31
}

It was just a few lines of code for the client and we significantly reduced the clutter regarding the instantiation of the objects, which has been delegated to the Spring IoC container. How does the container know how to create the objects? Well, we will need to provide the instructions to the container. We will select the xml metadata configuration approach, so the bean definition is contained in an external xml file. So…let’s look at the object definitions in the xml metadata files.

01
<?xml version="1.0" encoding="UTF-8"?>
02
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
03
<beans>
04
    <bean id="ContactsService"
05
          class="contactmanager.common.services.ContactsService">
06
        <!-- inline object -->
07
        <constructor-arg>
08
            <bean class="contactmanager.common.repository.ContactRepository" />
09
        </constructor-arg>
10
        <constructor-arg ref="EmailService" />
11
    </bean>
12
    <bean id="EmailService"
13
          class="contactmanager.common.services.EmailService" >
14
        <constructor-arg value="dummy.com" />
15
        <constructor-arg value="test@dummy.com" />
16
        <constructor-arg value="Hello!" />
17
        <constructor-arg value="Hello Email Contact!" />
18
    </bean>
19
</beans>

The element bean contains the instructions to instantiate and initialize an object. The id or name attribute is the reference name, which is the value that is passed when requesting an object from the IoC container. The class attribute is the namespace qualified class name. The primary bean child elements include the constructor-arg and property, which provide constructor and setter based dependency injection techniques.The value attribute is the static value, expression or placeholder. The ref attribute identifies the name or id of another bean element, so the value is set to this object.

Our Brick Contact Manager xml metadata example is only scratching the surface of the options available for defining your objects. Bean configuration and the popular elements and attributes supporting instantiation, inheritance, lifecycle, scope and the injection types (setter and property) are available.

The following is the output from the NetBeans IDE, where you can trace the calls based on the console writes.

The choice of the dependency injection type (i.e. constructor, setter or method) is sometimes a personal choice. I prefer defining a constructor for mandatory dependencies and setter properties for optional items. If you have too many mandatory items then your constructors become difficult to manage and configure using IoC.

Spring provides a robust set of IoC features that are too many to present in this post. You can download the Brick Contact Manager and review the code. You will find making changes is simple. The NetBeans and Eclipse development environments provide the libraries and templates to support Spring, so this minimizes the learning curve for Spring.

In summary, the Brick Contact Manager complements the Stick Contact Manager and solves the object creation responsibility problem. I have found that following the software design principles we have defined in Part II and implementing the patterns in Part IV are a good defense against premature end-of-life scenario for your applications. The addition of an IoC container will further promote the software design principles and add significant value to your product. You will find maintenance and change requests will be less painful.

I hope you found this series helpful and will be able to follow the concepts presented with your next project. I still receive messages from colleagues of previous projects as they continue to promote the design patterns and practices discussed in this series. If you are currently working a project then take a few minutes and perform an evaluation using our software design principles. Would your project benefit from the design patterns and concepts?

Source Code

Go to Top