The WiredChurch.com system we discuss in this case study is a .NET-based application that allows religious organizations to manage their community activities. In the previous article, we implemented a business services layer that performs two distinct tasks. The first task is managing the process of entering and updating the core database on behalf of the business façade. The second is silently managing the system functions through a series of business engines. Later in the series, we’ll cover the database and queuing technologies that provide data to these engines and objects. In this article, we focus on the theory, design, and implementation of these business services objects.
.NET case study
This is the third installment in a five-part series focusing on a real-world .NET implementation. Check out these other installments:
Business services objects
The basic function of the business services objects is to implement the rules of the business in an object hierarchy. If implemented properly, the business façade and the business services engines code is very straightforward because it knows nothing of the implementation of the objects. It knows only that there are certain methods and properties available to use when manipulating them. For example, one of the business objects used by WiredChurch is the Person object.
Implemented as a base class, the Person object includes the singleton properties Name and OrganizationID, as well as collections of other classes, including Addresses, Events, and a Group Memberships collection. Also, we encapsulate business processes inside the objects. For example, calling the Notify method of an instantiated Person object causes the system to initiate a process alerting the person using his or her default address.
All business services objects representing entities (e.g., Person and Event) contain standard Add, Update, and Delete methods that encapsulate the business rules surrounding those actions. For example, the business façade calls the Event.Add method and passes a typed data set containing the fields necessary to create a new event. The typed data set is actually created by a user control that passes the data set to the business façade events XML Web service. (See Designing scalable presentation services for more information on the business façade.) In order for a person to be registered for an event, the business façade simply calls the Person.Events().Add method with the Event object as a parameter. The business services layer takes care of the underlying systems logic.
Business services engines
In addition to a set of business objects that models the entities in the business, the business layer of WiredChurch also implements a series of “engines” that model the workflow of the business. Why do we need business services engines? Suppose I have an event requiring advanced registration. The business services objects handle accepting the event information from the business façade, but how are people notified about the event so that they have a chance to register? How do they get reminder notices in advance of the event?
These functions are handled by a series of engines. Whenever a person adds a new event, he or she specifies who should be allowed to attend. For example, only class members should be allowed to attend if the event is a class party. If a member is browsing the Web site, presentation-layer controls allow that person to see all events for which he or she is eligible.
What if a member doesn’t visit the Web site before the event? The WorkFlow engine handles this. The WorkFlow engine is designed to maintain the state of current system activities and trigger actions based on predefined action tables. Once the event is added to the system, the WorkFlow engine takes care of scheduling all event notifications, including an initial invitation to other eligible persons and reminders for registered persons.
Where the WorkFlow engine schedules activities, the Communications engine actually manages external e-mail, telephone, and postal mail correspondence with members. For example, the Communications engine may send out event notifications scheduled by the WorkFlow engine via e-mail with a link to a Web page allowing event registration.
The Communications engine can also process incoming messages. Rather than sending a link, the Communications engine can send an e-mail instructing the member to send an e-mail reply with a simple “Yes” or “No” indicating his or her interest in an event. The Communications engine processes the incoming mail and uses the business objects to indicate the member’s registration status.
Implementing the engines
The business services engines are implemented as Windows services. As such, they work at a system level and keep these key functions active at all times. Other common Windows services include SQL Server and the ASP.NET State Service. Before .NET, developing COM-based Windows services in prior versions of Visual Studio was either a black art reserved for Visual C++ developers or a hack performed by Visual Basic developers. However, Visual Studio .NET includes Windows services development templates as an integral part of the system.
Using Visual Studio .NET makes it simple to develop a Windows service, although debugging a service is still challenging since it has to be installed and run at a system level.
More importantly, by implementing these engines as Windows services that manage discrete operations using queues, scalability is increased. The engines can be installed on a single machine with the business objects, or the engines and objects may be installed on multiple machines. By using the LoadBalancingSupported attribute found in the System.EnterpriseServices namespace, you may specify that your .NET business objects participate in component load balancing provided by Windows 2000 Advanced Server. We may configure multiple machines running the business engines to pull from the same queues, thus dramatically increasing performance and scalability.
Business services instrumentation
In order to successfully implement a project of this size, you must thoroughly instrument the application. Application instrumentation includes documenting the results of key business-services functions in application event logs as well as exposing key application metrics to your operations teams using performance counters. Visual Studio .NET makes it almost trivial to add Windows event log and performance counter support to your applications. It’s now as simple as dragging a control to the design surface, setting some properties, and wiring the functions together with a few lines of code. You can even expose your business-services layer to external management consoles using the Windows Management Interface, or WMI. The .NET framework provides the System.Management.Instrumentation namespace to minimize the work required to make an application manageable through WMI and help you develop applications that generate WMI events.
The .NET framework has been a blessing during all phases of development of the WiredChurch.com system. This installment of my .NET case study has covered the implementation of business services. In the next article, I’ll dive into scalability issues and discuss how to address them with .NET.