Domain Repository .NET Code Examples
| Class Code | Class Description | Test Code | Test Description | |
| Select a content section anchor button and then use the Browser’s back button to return to selections | ||||
Technology Stack Code Example Details
A .NET Code Example for the Domain Repository
The Domain Repository Component has the responsibility to acquire the injected TechStackEntity State Object as a Command and return a Void to the calling Factory Component.
The Repository Component acquires its collection of Common Object Metadata, Tech Stack, Tech Stack Type Properties along with populating the related Stack Technologies and DevOps related technologies lists from either the MongoDB Distributed Cache System or a call to the Data Services Layer’s ORM.
When instantiated a MongoDB BsonObjectId is created as the Globally Unique Identifier for the Aggregate Root Domain Entity as defined by the Domain Driven Design specifications.
The MongoDB BsonObjectId becomes the Tech Stacks Cache dictionary’s Key/Value pair’s Value and paired with the Tech Stack Type string name as the dictionary’s Key in the Tech Stacks Cache dictionary of <string, BsonObjectId>.
A call is made to its Repository Class injecting the TechStackEntity State Object for population be either the Domain’s MongoDB Cache or the Data Services Layer’s Entity Framework ORM.
After the TechStackEntity State Object is populated, as a Command, the injected empty TechStackEntityResponse Object along with the populated TechStackEntity State Object are sent to Class Helper Methods.
As the final actions of the CQS Command the Helper Methods transforms TechStackEntity State Object data into the requested TechStackEntityResponse Object.
The Repository Module Component can now return a Void with the fully processed TechStackEntityResponse Object for the requesting Client’s Query for consumption through the Factory Component.
The Tech Stack Repository Class:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 |
using System.Linq; using AAP.DSL.Mongo.MongoDAL; using AAP.DSL.ORM.ORMSQL.Data.Technologists; using AAP.DSL.ORM.ORMSQL.Data.TechStackDevOps.TechStackTechnologyTypes; using AAP.DSL.SQLData; using AAP.LAD.Domain.TechStacks.Helpers; using AAP.LAD.Domain.TechStacks.Models.Entities; using AAP.LAD.Domain.TechStacks.Models.ValueObjects; using AAP.SharedKernel.DTOs; using AAP.SharedKernel.DTOs.Exceptions; using AAP.SharedKernel.DTOs.TechStacks.TechStackTechnologyTypes; using MongoDB.Bson; using MongoDB.Driver; namespace AAP.LAD.Domain.TechStacks.Repositories { public sealed class TechStackRepositories : SQLDataAccess { private static TechStacksDictionary TechStacksDictionary { get; set; } private static bool _isNewId { get; set; } private static BsonObjectId _documentId { get; set; } private static CreateMongoDocuments<TechStackEntity> _newMongoDocument { get; set; } private static ReadMongoDocuments<TechStackEntity> _readMongoDocuments { get; set; } public TechStackRepositories(string serverName = "local", string databaseName = "cdms-lad", string collectionName = "techStacks") { TechStacksDictionary = new TechStacksDictionary(); _newMongoDocument = new CreateMongoDocuments<TechStackEntity>(serverName, databaseName, collectionName); _readMongoDocuments = new ReadMongoDocuments<TechStackEntity>(serverName, databaseName, collectionName); } public void GetTechStackEntity(TechStackEntity stackEntity) { ValidateInputParameter(stackEntity); if (stackEntity.ErrorList.Count > 0) return; GetDocumentId(stackEntity.StackType.StackTechnologyType); GetEntityDocument(stackEntity); } public static void SaveTechStackEntity(TechStackEntity techStackEntity) { TechStacksDictionary.AddOrUpdateDictionaryEntry(TechStacksDictionary.CacheIdDictionary, techStackEntity.StackType.StackTechnologyType, TechStacksDictionary.GetCacheDictionaryId(techStackEntity)); StoreTechStackEntityInMongoDB(techStackEntity); } #region Helpers private static void ValidateInputParameter(TechStackEntity stackEntity) { if (stackEntity == null) stackEntity.ErrorList.Add(new ErrorInfoDTO { Message = "ERROR: No Stack Entity provided" }); if (stackEntity.StackType.StackTechnologyType == null) stackEntity.ErrorList.Add(new ErrorInfoDTO { Message = "ERROR: No Stack Technology Type provided" }); } private static void GetDocumentId(string entityName) { if (TechStacksDictionary.CacheIdDictionary[entityName] != null) return; _documentId = new BsonObjectId(ObjectId.GenerateNewId()); TechStacksDictionary.AddOrUpdateDictionaryEntry(TechStacksDictionary.CacheIdDictionary, entityName, _documentId); _isNewId = true; } private static void CreateEntityDocumentFromORM(TechStackTypesResponseDTO response, TechStackEntity stackEntity) { stackEntity.TechStackEntityId = (ObjectId) _documentId; stackEntity.TechStack.StackName = response.TechStack.StackName; stackEntity.TechStack.StackDescription = response.TechStack.Description; stackEntity.TechStack.StackOrder = response.TechStack.StackOrder; stackEntity.TechStack.StackLogoEmblem = response.TechStack.LogoEmblem; stackEntity.StackType.StackTechnologyType = response.TechStackType.StackTechnologyType; stackEntity.StackType.StackTypeDescription = response.TechStackType.Description; stackEntity.StackType.StackTypeStackOrder = response.TechStackType.StackOrder; stackEntity.StackType.StackTypeLogoEmblem = response.TechStackType.LogoEmblem; stackEntity.StackTechnologyList = response.TechStackType.TechStackTechnologiesList .Select(x => new StackTechnology { StackTechnologyName = x.StackTechnology, StackTechnologyDescription = x.Description, StackTechnologySortOrder = x.StackOrder, StackTechnologyLogoEmblem = x.LogoEmblem }).ToList(); stackEntity.TechDevOpsList = response.TechStackTechnology.TechDevOpsList .Select(x => new TechDevOps { DevOpsId = x.DevOpsId, Technology = x.Technology, InfoURL = x.InfoURL, TechnologyDescription = x.TechnologyDescription, IsActive = x.IsActive, TechnologyOrder = x.TechnologyOrder, LogoEmblem = x.LogoEmblem, TechnologyArena = x.TechnologyArena, TechnologyCategory = x.TechnologyCategory, MaturityStage = x.MaturityStage, IsTrending = x.IsTrending, IsOpenSource = x.IsOpenSource, CreatedBy = x.CreatedBy, Created = x.Created, UpdatedBy = x.UpdatedBy, Updated = x.Updated }).ToList(); stackEntity.ErrorList = response.ErrorList; stackEntity.RequestTimeStamp = response.RequestTimeStamp; stackEntity.ResponseTimeStamp = response.ResponseTimeStamp; stackEntity.TransactionId = response.TransactionId; stackEntity.SessionId = response.SessionId; stackEntity.CacheExpirationTime = response.CacheExpirationTime; stackEntity.CacheKey = response.CacheKey; stackEntity.IsCacheEnabled = response.IsCacheEnabled; stackEntity.IsCached = response.IsCached; stackEntity.IsDataFromCached = response.IsDataFromCached; stackEntity.IsLoggingEnabled = response.IsLoggingEnabled; stackEntity.DTODeliveryDurationInMilliseconds = response.DTODeliveryDurationInMilliseconds; stackEntity.DataAccessDurationInMilliseconds = response.DataAccessDurationInMilliseconds; stackEntity.SystemMessage = response.SystemMessage; stackEntity.UserId = response.UserId; stackEntity.SystemMessage.Message = string.Format("Tech Stack '{0}' was sucessfully created with ID: '{1}' " + "at UTC Time: '{2}' with a Stack Technology Count of '{3}' " + "and a DevOps Technology Count of '{4}' by User: '{5}' for the '{6}' Stack Technology Type.", stackEntity.TechStack.StackName, stackEntity.TechStackEntityId.ToString(), stackEntity.TechStackEntityId.CreationTime, stackEntity.StackTechnologyList.Count, stackEntity.TechDevOpsList.Count, TechnologistsORMSQL.GetUserFullName(stackEntity.UserId), stackEntity.StackType.StackTechnologyType); stackEntity.Success = true; } private static void StoreTechStackEntityInMongoDB(TechStackEntity techStackEntity) { if (_isNewId) _newMongoDocument.InsertOneDocument(techStackEntity); } private static void ReadTechStackEntityInMongoDBCache(string stackType) { var id = TechStacksDictionary.CacheIdDictionary[stackType]; var filter = Builders<TechStackEntity>.Filter.Eq("_id", id); var errorObject = new BaseResponseDTO(); _readMongoDocuments.ReadOneDocument(filter, errorObject); } private void GetEntityDocument(TechStackEntity stackEntity) { if (!_isNewId) ReadTechStackEntityInMongoDBCache(stackEntity.StackType.StackTechnologyType); var request = new TechStacksTypesRequestDTO { StackTechnologyType = stackEntity.StackType.StackTechnologyType }; var response = new TechStackTypesResponseDTO(); this.GetTechStackTypeByStackTechnologyType(response, request); if (!response.Success) return; CreateEntityDocumentFromORM(response, stackEntity); StoreTechStackEntityInMongoDB(stackEntity); _isNewId = false; } #endregion } } |
The Tech Stack Repository Class Code Description:
The Using Statements:
The Namespace of Advanced Application Platform [AAP] and Laser Application Delivery [LAD] represents the Hybrid .NET / MEAN.js framework solution: AAP.LAD.
We are working in the Domain Layer
with strict Separation of Concerns and Data Hiding
The Repository Class only has knowledge of its next lower module, the Infrastructure Data Services Layer’s ORM, the Entity State Objects and the Shared Kernel Base DTO for its Exception Handling and Metadata Properties.
The Repository Module Component queries for a MongoDB Object Id from the Distributed Cache Tech Stack Dictionary using the Tech Stack Type as the dictionary’s Key.
If the Dictionary’s Value is Null A Command is sent with an injected Request and Response Tech Stack Types POCO DTO Objects.
The Data Services Layer ORM processes the request and populates the Tech Stack Types Response Object from either the In-memory Cache System or Queries the Entity Framework ORM for the components from the SQL Database.
If the Cache Dictionary’s Value is Not Null the MongoDB Object Id in the MongoDB Cache Dictionary’s Value is used to retrieve the Tech Stack Entity Complex Document file and converted to a JSON format for consumption by the Services Module.
The Class Constructor:
The Tech Stack Factory class uses a “Parameterized” constructor to pass the MongoDB Server, Database and Collection names.
These parameters are used to create the Tech Stack Repository using the correct instance of MongoDB.
Default parameters are in place for the
local server with a default
database and collection assignment
but it is best practice to explicitly
define the MongoDB
connection string information
The constructor also creates the Tech Stack Dictionary for use as a private Static Property.
The Mongo Object Entity Type Contexts are created for Read and Create CRUD functions using a generic Mongo Data Access TEntity class.
The Example Method:
The SaveTechStackEntity() method processes the injected TechStackEntity object.
The TechStackEntityResponse object is populated for final processing by the calling Domain Service Module as a Command and then returning a Void.
As before. a Return of Void
is in the CQS Principle Requirements
A Void return is possible because the Dependency Injected Response Object is “In-scope” and populated for the Services Module when returned to the Services class.
The Helper Methods:
The Factory Helper Methods encapsulate to functionality, using the Open/Closed Principle, of the data transformation activities for the Tech Stack Info, Tech Stack Type and the Base Class Metadata for Exception Handling and Request Object’s State Parameters.
The helper methods also store a new Stack Entity in the MongoDB, as required.
The Open /Closed Principle is used here to “Open” the possibility to change the “Transformation Results” without changing the Tech Stack Factory’s calling PopulateTechStack() method.
The Calling Method is Closed for Modification
but Open for Changing the results
through the Class Helper Methods
The Tech Stack Repository Class Test Suite:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 |
using System; using AAP.LAD.Domain.TechStacks.Models.Entities; using AAP.LAD.Domain.TechStacks.Repositories; using Microsoft.VisualStudio.TestTools.UnitTesting; using MongoDB.Bson; using MongoDB.Bson.IO; namespace AAP.LAD.TestSuite.Domain.TechStacks.Repositories { public class TechStackRepositoriesTests { [TestClass] public sealed class GivenIWantToTestTheTechStackRepositoriesClass { private TechStackRepositories _techStackRepositories { get; set; } public GivenIWantToTestTheTechStackRepositoriesClass() { _techStackRepositories = new TechStackRepositories(); JsonWriterSettings.Defaults.Indent = true; } #region Happy Tests #region GetTechStackEntity [TestMethod] public void WhenICallTheGetTechStackEntityyMethodWithNoDictionaryEntry_ThenIWillValidateTheObjectResultFromTheORM() { // Arrange const string entityName = "MEAN"; var techStackEntity = new TechStackEntity(entityName); _techStackRepositories.GetTechStackEntity(techStackEntity); // Act var result = techStackEntity; // Assert Assert.IsNotNull(result); Console.WriteLine(); Console.WriteLine("Tech Stack Entity: " + result.ToJson()); Console.WriteLine(); } [TestMethod] public void WhenICallTheGetTechStackEntityMethodWithDictionaryEntry_ThenIWillValidateTheObjectResultFromTheMongoCache() { // Arrange const string entityName = "B-MEAN"; var techStackEntity = new TechStackEntity(entityName); _techStackRepositories.GetTechStackEntity(techStackEntity); // Act var result = techStackEntity; // Assert Assert.IsNotNull(result); Console.WriteLine(); Console.WriteLine("Tech Stack Entity: " + result.ToJson()); Console.WriteLine(); } #endregion #region SaveTechStackEntity [TestMethod] public void WhenICallTheSaveTechStackEntityMethodWithDictionaryEntry_ThenIWillValidateTheObjectResultFromTheMongoCache() { // Arrange const string entityName = "B-MEAN"; var techStackEntity = new TechStackEntity(entityName); TechStackRepositories.SaveTechStackEntity(techStackEntity); // Act var result = techStackEntity; // Assert Assert.IsNotNull(result); Console.WriteLine(); Console.WriteLine("Tech Stack Entity: " + result.ToJson()); Console.WriteLine(); } #endregion #endregion } } } |
The Tech Stack Repository Class Test Suite Description:
The Test Class Constructor:
We create an instance of the Class Under Test (CUT) as a Private Encapsulated Property: _techStackRepositories within the Gherkin Language naming convention:
Given | When | Then
A “JsonWriterSettings.Defaults.Indent = true” statement is executed to format the Assert to the Command Console the Returned JSON Object for Eyes-on Viewing for final validation.
The Test Method Arrange:
We select the value for the Stack Type: “MEAN”.
We then create the TechStackEntity and set the StackTechnologyType to the selected Stack Type: “MEAN”.
We call the Method Under Test: _techStackRepositories.GetTechStackEntity(techStackEntity) in this section rather than the ACT Section due to the Void return type.
We will Assert against the newly populated injected TechStackEntity Object.
The Test Method Act:
Since this is a Command with a Void return type we simply set the Results variable to the populated TechStackEntity Object for Assertions.
The Test Method Asserts:
We evaluate the results by checking for a null response and convert the POCO Object to JSON for viewing in the Test Console as it would be seen by the Microservice and the Client.
We could validate all of the relevant properties as we did in the higher Services module but that would be redundant as that test validates the Factories results.
Wisdom Pearl # 140 – Tools of the Trade
The Right Technology Tool
… For the Right Technology Solution Job
…… Always be Diligent in Keeping Your Development Toolbox Up to Date
The following two tabs change content below.
I am a Principal Architect at Liquid Hub in the Philadelphia area specializing in Agile Practices as a Certified Scrum Master (CSM). I use Test Driven Development (TDD) and Acceptance Test Driven Development (ATDD) with Behavior Driven Development (BDD) as my bridge to Agile User Stories Acceptance Criteria in a Domain Driven Design (DDD) implementing true RESTful services
Latest posts by Brad Huett (see all)
- DevOps: A Bridge to Your DevOps Culture - March 25, 2016
- Embracing Test Driven Development (TDD) - March 25, 2016
- DevOps: Delivering Agile Projects - March 25, 2016


