Archive for September, 2012

Project Management 101 For Developers (Part I)

1

As software developers and engineers, we have daily project management exposure. I am not a Project Manager, because I have a passion for enterprise architecture and pure coding. I also have a desire to learn and broaden my complementary skills, so I enrolled in project management courses and training seminars. As a team lead and senior software engineer, the skills are invaluable to the project team. If you attend project meetings and scratch your head when you hear work breakdown structure, scope, critical path, float, Gantt, PERT and other alien words then a quick guide to project management terms and concepts would be helpful. So…if you seek a better understanding then this article will provide a foundation.

Project vs. Program

A project is temporary, where a start and end is understood to deliver a product or service. A collection of related projects can be combined to form a program. The program management is a higher level with a focus on coordinating the use of resources across multiple projects. Project management requires applying the appropriate skills and techniques to activities, so project requirements are satisfied.

Project Constraints

The project constraints can be categorized as the following.

  • Scope – the project work to be performed
  • Cost – the resources required to successfully complete a project
  • Time – the schedule

The project management challenge is balancing scope, cost and schedule. The three constraints will affect each other, so careful planning and control is required to keep the balance. If the client requests an accelerated schedule then cost will rise with additional resource demands or a scope reduction will be required. As you can see, a simple adjustment to any constraint will impact the others.

Project Life-cycle

A project is usually divided into four phases.

  • Initiation – defining business needs, requirements collection
  • Planning – delivering the project plan
  • Implementation - execution of the plan while monitoring and controlling
  • Closing – resource allocation, post-mortem reviews

Initiation – Project Selection

The project go/no-go decision should involve a process to evaluate a proposal using quantitative and qualitative factors, but most importantly satisfy the organizations objectives.

The quantitative approach is primarily based on cost, where several formulas provide the decision making guidance. The following are just a few of the costing formulas.

  • Benefit-Cost Ratio (BCR)
  • Present Value (PV)
  • Net Present Value (NPV)

The BCR compares the benefits to the overall costs using the BCR = Benefit / Cost formula. If you have a $100 return on a $50 investment then the BCR is 2:1. A higher BCR is better and less than 1 should not be accepted. This formula has many drawbacks, which includes no concept of the time value of money. Inflation is a perfect example – money received today is worth more in the future.

The Present Value (PV) formula provides the value today for future cash flows using PV = FV / (1 + i)n. The FV is the future value and i represents the interest rate as n is the number of time periods.

The final formula, NPV, compares two options using the PV formula and comparing the results. In general, the time factor will ensure multiple options can be evaluated fairly.

The formulas are examples of quantitative factors, so qualitative techniques involve bias, risk and strategic plan. These factors must also be considered when preparing a go/no-go decision.

Needs, Objectives and Requirements

A project originates from one or more needs, although not all participants will agree. The needs are identified using focus group interviews, surveys, audits and reviewing existing documentation.

The needs will evolve into objectives, which should follow the SMART model.

  • Specific
  • Measurable
  • Agreed-upon
  • Realistic
  • Time-constrained

The requirements are the next step in the evolution of an objective. A functional requirement describes the customer’s expectation or what must happen. A technical requirement is the implementation of a functional requirement developed by the project team.

They are keys to success and a failure to deliver strong requirements will most likely negatively impact the project. The authors should remain focused on the objective of the deliverable. The functional requirements should not define the implementation.

In my experience, poor objectives or requirements are one of the leading causes of project failures. If you follow the SMART model then you will avoid this trap. I also follow the SMART model when establishing my personal objectives, so it is easier to evaluate my progress and performance during a review.

Planning

The second project life-cycle phase is Planning, where the scope and work breakdown structure (WBS), schedule, costs and resources are defined. A core project team is selected as a small group of key individuals. The major components of planning are

  1. Schedule
  2. Cost
  3. Resource
  4. Risk
  5. Quality and Test

The planning may also include procurement and communication, but this will be driven by the project. The final deliverable is the project plan, which is the collection of all the planning components.

Scope

Scope is another term that will appear during the project life-cycle, which is the sum of the project work (i.e. services, products). At this phase, the scope planning will require the details and the result will be the scope statement.

Work Breakdown Structure (WBS)

The scope evolves into the WBS, which is hierarchical representation of the work to satisfy the project objectives. This is decomposition of the work, so smaller and more manageable items are identified. You cannot accurately estimate resources, budget or schedule without the WBS.

The work package and control account are the primary levels of the WBS. A work package should be sized to assign an individual or small team. The control accounts represent the level costs are tracked, which is generally for senior management. The WBS can be presented in a graphical chart or a traditional indented form. Microsoft Project and similar tools are available, so building and maintaining the WBS is simple using the templates.

In general, a well-designed WBS will be the source of all project management tools. A top-down design approach is the most effective method for building the WBS as you decompose the project into smaller items. Since the work breakdown does not contain item detail, a WBS Dictionary is available to collect the details about the work package.

Schedule Planning and Estimating

The next planning task is scheduling, which requires estimating time, costs and resources. There are several estimating methods and tools available to assist, which include the following.

  • Program Evaluation and Review Technique (PERT)
  • Wideband Delphi
  • 3-point

The PERT process collects four time estimates per activity – most pessimistic, most optimistic and most likely. The team lead collects the estimates and applies a standard deviation calculation to produce the expected result. The formula is (most optimistic + (most likely x 4) + most pessimistic) / 6. You can use this approach for time and cost estimates. For example: you optimistically feel a task can be completed in 12 days, pessimistically in 19 and most likely in 16. The calculation would be the following.

Estimated Duration = (12 + (16 x 4) + 19) / 6

Estimated Duration = 15.8333 days

The Wideband Delphi technique requests the participation of subject-matter experts to provide a single estimate. The values are averaged and discussions begin to refine the estimate until a consensus is reached.

The 3-point estimate is an average of the same optimistic, pessimistic and most likely outcome. The formula is (Optimistic + Most Likely + Pessimistic) / 3. This formula is similar to PERT, but it does not weight the scenarios. 

I have participated in several PERT, Wideband Delphi and 3-point estimating sessions for projects. The importance of estimating cannot be understated, since it will play an important role in the success of the project. It is very common for participants to simply identify the optimistic and pessimistic values and split the most likely. If you apply some thought to the estimating then you will realize this should not always be the case. I apply risk factors to my estimates, which can result in significant deviations.

At this point, we have collected the time estimates using one or more of the techniques. The next planning step is scheduling, which also includes several tools and techniques.

  • Network Diagram (Precedence Diagramming Method, Critical Path Method)
  • Gantt Chart

The scheduling challenge is incorporating the resource availability and productivity factors to the duration estimates. If a team member is assigned to multiple projects then you cannot allocate 100% time to a task. The experience level of a team member will impact the productivity, so you cannot expect a junior software engineer to complete a task as quickly as a senior. Finally, the third factor is the relationship or dependency of one task to another. For example: you must stand-up a web server before you can deploy the application. It is also possible that multiple dependencies could exist as predecessors and successors.

Once you have compiled your time estimates and relationships, you can calculate the earliest time an activity can start and end. This is called the forward pass. The following is a simple network diagram to illustrate the multiple forward pass calculation.

In this example, the A time estimate is 5 days. B and C will start at day 5, since A is a predecessor to the tasks. The finish day is based on the time estimates, so B is 5 and C is 10. Since the D start day is based on the completion of B and C, the earliest start is 15. This is the predecessor that finishes last, which is C.

Since we have a forward pass, we must have a backward pass to calculate the latest time a task can start and end without delaying the project completion. This will provide the values for calculating the project float time, which is the difference between the early and late end/finish dates. 

After completing the above calculations, the Network Analysis will expose the project duration, float and critical path. The new term, critical path, represents the longest series of tasks or minimum duration of the project. If the tasks on the critical path do not start on time then it is likely the project will be delayed. The critical path is identified using the tasks with the lowest float value. The project manager will carefully monitor the critical path and apply resources to ensure the project remains on schedule, although non-critical path tasks are also important to the project success and must not be overlooked. 

A Gantt chart is a graphical representation of the project tasks or activities depicted as horizontal bars based on a time scale. The task start, finish and durations are marked. This chart is one of the most recognized items and like the previous tasks is available using Microsoft Project. All planning tasks are simplified using tools, but the ability to calculate manually is helpful to understand the concepts. 

Cost Planning

It is great we have a project schedule, but now the focus turns to the budget. You should include the WBS work package costs as well as overhead, reserves and indirect costs. The source of the estimates can be historical information, outside consultants/estimators and your subject-matter experts. The types of cost estimates include order-of-magnitude, budgetary and definitive.

The order-of-magnitude is a preliminary cost estimate with a lower accuracy. A budgetary estimate is conducted with a high-level design available, so the accuracy is an improvement over the order-of-magnitude. A definitive estimate is completed after the detailed design is available, which is the most accurate of the three types.

A direct cost includes labor, materials and equipment costs required to complete the project. An indirect cost could include general and administrative, sales and marketing expenses. These costs will be incurred with or without the project, but must be partially absorbed at the project level. A simple cumulative cost curve will illustrate the costs over time.

Resource Planning

The schedule and cost planning is complete, so now we must address the resources required to complete the project. This could include personnel, equipment and facilities. If your organization maintains a pool of people resources then you can work internally to identify the appropriate personnel with the skills and experience for a task. Alternatively, you can work with outside organizations to contract personnel to complete specific tasks. As a project manager, your goal is to assemble a team with the best resources available. In the end, the people will be the greatest asset and pave the way to a successful project. The following are a few common tools for resource planning.

  • Roles/Responsibility Matrix
  • Resource Gantt Chart
  • Resource Loading Table and Histogram
  • Resource Leveling

The Roles/Responsibilities matrix is a simple table aligning people to a task. The Resource Gantt chart, as explained previously, is a bar graph format. The resource loading table depicts the resource needs based on time, which feeds the resource loading histogram as a vertical bar graph illustrating resource by time. Finally, resource leveling focuses on adjustments required to meet the project objectives.

In my experience, assembling a project team requires an understanding of each candidate and aligning them with the tasks leveraging their strengths. During larger projects, I prefer the assembly-line development approach. The individuals will be segregated into smaller focus teams, where the tasks are based on traditional application tiers. This includes presentation, business and data. In general, software engineers and developers excel or prefer working in one of the tiers. When assigning team members to complete tasks including all tiers, the overall efficiency decreases as some struggle to complete tasks without experience. Again, this is my observation and experiences formulating this general approach to resource planning.

Risk Planning

Risk is also included in the planning phase, which is an uncertain event having a positive or negative impact on the project. Risk analysis should occur throughout a project, which also includes the selection during the Initiation phase. We are most concerned with risk probability and impact. We must identify risks, perform an analysis, response planning and monitoring/controlling.

I would consider any of the previous discussed processes as a risk when you are not confident in the result. If you did not develop SMART objectives or sufficient functional requirements then this is a project risk. If you are unable to locate an important subject-matter expert to complete a task then this is also a project risk. If equipment is not delivered on time then this is a project risk.

It is not enough to just identify a risk and assign the probability of occurrence and impact. The response planning is your action to accept, mitigate, transfer or avoid the risk. When you choose risk mitigation, you are reducing the probability or impact of a risk. If you select a transfer strategy then you shift the risk to another party.

The Implementation phase is also critical, since you must continue to monitor and control risk. You can perform a great job of identifying a risk, formulating a response plan but fail to control the risk during implementation. I’ve participated in projects where this is the case, which is frustrating when you plan for the risk.

Quality and Test Planning

Finally, quality assurance and quality control are critical to your overall success. You should not sacrifice quality to meet schedule, because your reputation will suffer and negatively impact your ability to win future contracts. If you discover and correct defects early then you will significantly reduce your costs. A comprehensive Test Plan containing detailed test criteria will serve as user acceptance and provides the guidance for all participants. The project team should ensure all test criteria is satisfied prior to user acceptance testing.

I am a supporter of many agile practices, including a focus on delivering a quality product. This includes Continuous Integration (CI) and Test-Driven Development (TDD), although building unit level tests outside of the TDD concept are also very effective. Test early and often is the key! The availability of open source and commercial tools will accelerate the process to adopt the principles and your investment will improve quality. The higher your test coverage (i.e. percentage of code paths covered by your tests) and a continuous testing process will improve your quality. The cost of discovering and fixing a defect increases significantly during the later stages of the Implementation phase, so quality planning is a critical component.  

The result of all the planning is the project plan, which is the guide for the Implementation phase. In Part II of the series, we will continue the project life-cycle with the Implementation and Closing phases.

Part II

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

Go to Top