Table of Contents

Code Structure - Services

Services are centralized, stateful feature providers that can be globally reached from user code, test methods, blocks, types or other services. They are an integral part of the overall use model reflecting recommended practice to use the tester.

As such, their use model and functionality is being relied on in user code, with significant impacts in the case of incompatible changes. C#RA aims to minimize breaking changes through careful design and compatible extensions whenever possible.

Services follow C#RA's compatibility philosophy, striving to maintain backward compatibility while allowing necessary improvements. Implementation is realized as a static class with consistent patterns across all services.

Important

Calls to Services from within the C# Reference Architecture follow best practices and are updated when improvements are introduced.

File & Folder Structure

All Services follow a consistent scheme. The following examples will use the AlertService as reference:

🌐 Csra
    📂 Implementations                      
        📁 ExtensionMethods                 
        📂 Services                         
            📂 Alert                        <-- dedicated folder for each service
                📄 AlertService.cs          <-- implementation file(s)
            📁 ...                          
        📁 TestBlocks                       
    📁 TestMethods                          
    📁 Types                                
    📂 Services                         
        📂 Alert                        <-- dedicated folder for each service
            📄 AlertService.cs          <-- public API class
            📄 IAlertService.cs         <-- interface class
        📁 ...                          
        📄 IService.cs                  <-- common design pattern for all services

🌐 UT
    📁 ExtensionMethods_UT                 
    📂 Services_UT                      
        📂 Alert_UT                      
            📄 AlertService_UT.cs           <-- unit tests
    📁 TheLib_UT                 

Interface Class

The interface definition holds all public nodes along with the XML documentation:

API Class

The API is a partial class holding the singleton object and implements the interface. Calls are handed through to the implementation:

Implementation Class

The implementation class holds the actual functionality:

Common Design Pattern

To facilitate certain commonality across all C#RA services, they implement the IService interface:

namespace Csra {

    public interface IService {

        /// <summary>
        /// Initialize the service. This is called by the API when the service is first used.
        /// </summary>
        void Reset();
    }
}

At this point, only a common Reset() method is required. Besides the consistent use model, this helps avoiding state leakage in consecutive unit tests: all services are reset in test initialization.

Unit Testing

Since they provide central capability for a broad and diverse range of use cases, Services are extensively unit tested. Not only should line coverage be at 100%, but the goal is to really try all corner cases and combinations, so that users can rely on flawless functionality:

using Moq;
using System;
using System.IO;
using Csra;
using Teradyne.Igxl.Interfaces.Public;
using static Csra.Api;
using MsTest = Microsoft.VisualStudio.TestTools.UnitTesting;

namespace Services_UT {

    [MsTest.TestClass]
    public class AlertService_UT : UT.CsraUnitTestBase {

        [MsTest.DataTestMethod]
        [MsTest.DataRow(0)]
        [MsTest.DataRow(AlertOutputTarget.OutputWindow)]
        [MsTest.DataRow(AlertOutputTarget.OutputWindow | AlertOutputTarget.Datalog)]
        [MsTest.DataRow(AlertOutputTarget.OutputWindow | AlertOutputTarget.File)]
        [MsTest.DataRow(AlertOutputTarget.OutputWindow | AlertOutputTarget.Datalog | AlertOutputTarget.File)]
        public void LogTarget(AlertOutputTarget input) {
            AlertOutputTarget outputDefault = AlertOutputTarget.OutputWindow;

            Services.Alert.LogTarget = input;

            MsTest.Assert.AreEqual(input | outputDefault, Services.Alert.LogTarget);
        }