diff --git a/.gitignore b/.gitignore
index 9cfdca04..eb7bb686 100644
--- a/.gitignore
+++ b/.gitignore
@@ -331,3 +331,4 @@ ASALocalRun/
/build/dnn-template-render
/build/content
/build/content-repo
+/WebApi/Eisk.WebApi/Properties/ServiceDependencies/eisk-webapi-1 - Web Deploy/profile.arm.json
diff --git a/.gitmodules b/.gitmodules
deleted file mode 100644
index e08ab148..00000000
--- a/.gitmodules
+++ /dev/null
@@ -1,3 +0,0 @@
-[submodule "Core"]
- path = Core
- url = https://github.com/EISK/eisk.core.git
diff --git a/Core b/Core
deleted file mode 160000
index bd729e7c..00000000
--- a/Core
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit bd729e7c1b801066be71cbaf36fc6008ea926d56
diff --git a/Core/Eisk.Core.Tests/Eisk.Core.Tests.csproj b/Core/Eisk.Core.Tests/Eisk.Core.Tests.csproj
new file mode 100644
index 00000000..5bdb9bf0
--- /dev/null
+++ b/Core/Eisk.Core.Tests/Eisk.Core.Tests.csproj
@@ -0,0 +1,22 @@
+
+
+
+ net6.0
+
+ false
+
+
+
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
+
+
+
+
+
diff --git a/Core/Eisk.Core.Tests/UnitTest1.cs b/Core/Eisk.Core.Tests/UnitTest1.cs
new file mode 100644
index 00000000..a7d0ffcf
--- /dev/null
+++ b/Core/Eisk.Core.Tests/UnitTest1.cs
@@ -0,0 +1,12 @@
+using Xunit;
+
+namespace Eisk.Core.Tests;
+
+public class UnitTest1
+{
+ [Fact]
+ public void Test1()
+ {
+
+ }
+}
diff --git a/Core/Eisk.Core/DataService/EFCore/EntityDataService.cs b/Core/Eisk.Core/DataService/EFCore/EntityDataService.cs
new file mode 100644
index 00000000..f5f11392
--- /dev/null
+++ b/Core/Eisk.Core/DataService/EFCore/EntityDataService.cs
@@ -0,0 +1,50 @@
+using Microsoft.EntityFrameworkCore;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+
+namespace Eisk.Core.DataService.EFCore;
+
+public class EntityDataService : IEntityDataService where TEntity : class, new()
+{
+ protected readonly DbContext DbContext;
+
+ public EntityDataService(DbContext dbContext)
+ {
+ DbContext = dbContext;
+ }
+
+ public virtual async Task GetById(TId id)
+ {
+ return await DbContext.Set().FindAsync(id);
+ }
+
+ public virtual async Task> GetAll()
+ {
+ return await DbContext.Set().ToListAsync();
+ }
+
+ public virtual async Task Add(TEntity entity)
+ {
+ var obj = DbContext.Add(entity);
+
+ await DbContext.SaveChangesAsync();
+
+ return obj.Entity;
+ }
+
+ public virtual async Task Update(TEntity entity)
+ {
+ var obj = DbContext.Update(entity);
+
+ await DbContext.SaveChangesAsync();
+
+ return obj.Entity;
+ }
+
+ public virtual async Task Delete(TEntity entity)
+ {
+ DbContext.Remove(entity);
+
+ await DbContext.SaveChangesAsync();
+ }
+}
diff --git a/Core/Eisk.Core/DataService/IEntityDataService.cs b/Core/Eisk.Core/DataService/IEntityDataService.cs
new file mode 100644
index 00000000..250d5234
--- /dev/null
+++ b/Core/Eisk.Core/DataService/IEntityDataService.cs
@@ -0,0 +1,13 @@
+using System.Collections.Generic;
+using System.Threading.Tasks;
+
+namespace Eisk.Core.DataService;
+
+public interface IEntityDataService where TEntity : class, new()
+{
+ Task GetById(TId id);
+ Task> GetAll();
+ Task Add(TEntity entity);
+ Task Update(TEntity entity);
+ Task Delete(TEntity entity);
+}
diff --git a/Core/Eisk.Core/DomainService/DomainService.cs b/Core/Eisk.Core/DomainService/DomainService.cs
new file mode 100644
index 00000000..accf6e0c
--- /dev/null
+++ b/Core/Eisk.Core/DomainService/DomainService.cs
@@ -0,0 +1,100 @@
+using Eisk.Core.Exceptions;
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+
+namespace Eisk.Core.DomainService;
+
+using DataService;
+using Utils;
+
+public class DomainService
+ where TDomain : class, new()
+{
+ readonly IEntityDataService _entityDataService;
+
+ public DomainService(IEntityDataService entityDataService)
+ {
+ _entityDataService = entityDataService;
+ }
+
+ public virtual async Task> GetAll()
+ {
+ return await _entityDataService.GetAll();
+ }
+
+ public virtual async Task GetById(TId id)
+ {
+ if (id.IsNullOrEmpty())
+ ThrowExceptionForInvalidLookupIdParameter();
+
+ var entityInDb = await _entityDataService.GetById(id);
+
+ if (entityInDb == null)
+ ThrowExceptionForNonExistantEntity(id);
+
+ return entityInDb;
+ }
+
+ public virtual async Task Add(TDomain entity)
+ {
+ return await Add(entity, null);
+ }
+
+ public virtual async Task Add(TDomain entity, Action preProcessAction, Action postProcessAction = null)
+ {
+ if (entity == null)
+ ThrowExceptionForNullInputEntity();
+
+ preProcessAction?.Invoke(entity);
+
+ var returnVal = await _entityDataService.Add(entity);
+
+ postProcessAction?.Invoke(returnVal);
+
+ return returnVal;
+ }
+
+ public virtual async Task Update(TId id, TDomain newEntity)
+ {
+ return await Update(id, newEntity, null);
+ }
+
+ public virtual async Task Update(TId id, TDomain newEntity, Action preProcessAction, Action postProcessAction = null)
+ {
+ if (newEntity == null)
+ ThrowExceptionForNullInputEntity();
+
+ var oldEntity = await GetById(id);
+
+ preProcessAction?.Invoke(oldEntity, newEntity);
+
+ var returnVal = await _entityDataService.Update(newEntity);
+
+ postProcessAction?.Invoke(returnVal);
+
+ return returnVal;
+ }
+
+ public virtual async Task Delete(TId id)
+ {
+ var entityInDb = await GetById(id);
+
+ await _entityDataService.Delete(entityInDb);
+ }
+
+ protected virtual void ThrowExceptionForNullInputEntity()
+ {
+ throw new NullInputEntityException();
+ }
+
+ protected virtual void ThrowExceptionForInvalidLookupIdParameter()
+ {
+ throw new InvalidLookupIdParameterException();
+ }
+
+ protected virtual void ThrowExceptionForNonExistantEntity(TId idValue)
+ {
+ throw new NonExistantEntityException(idValue);
+ }
+}
diff --git a/Core/Eisk.Core/Eisk.Core.csproj b/Core/Eisk.Core/Eisk.Core.csproj
new file mode 100644
index 00000000..56861b2e
--- /dev/null
+++ b/Core/Eisk.Core/Eisk.Core.csproj
@@ -0,0 +1,13 @@
+
+
+
+ net6.0
+ Library
+
+
+
+
+
+
+
+
diff --git a/Core/Eisk.Core/Exceptions/CoreException.cs b/Core/Eisk.Core/Exceptions/CoreException.cs
new file mode 100644
index 00000000..87ae1cf5
--- /dev/null
+++ b/Core/Eisk.Core/Exceptions/CoreException.cs
@@ -0,0 +1,31 @@
+using System;
+
+namespace Eisk.Core.Exceptions;
+
+public class CoreException : Exception
+{
+ private const string DefaultErrorCode = "APP-ERROR-000";
+
+ private string _message;
+ public override string Message => _message ?? (_message = ConvertToSentence(GetType().Name, ErrorCode));
+
+ private string _errorCode;
+
+ ///
+ /// Error code helps distringuishing same types of errors in different context.
+ ///
+ public string ErrorCode => _errorCode ?? (_errorCode = DefaultErrorCode);
+
+ public CoreException(string message = null, string errorCode = null)
+ {
+ _message = message;
+ _errorCode = errorCode;
+ }
+
+ //TODO: convert class name to sentence
+ static string ConvertToSentence(string message, string errorCode)
+ {
+ return errorCode + ": " + message;
+ }
+
+}
diff --git a/Core/Eisk.Core/Exceptions/DomainException.cs b/Core/Eisk.Core/Exceptions/DomainException.cs
new file mode 100644
index 00000000..fae600ba
--- /dev/null
+++ b/Core/Eisk.Core/Exceptions/DomainException.cs
@@ -0,0 +1,9 @@
+namespace Eisk.Core.Exceptions;
+
+public class DomainException : CoreException
+{
+ public DomainException(string message = null, string errorCode = null) : base(message, errorCode)
+ {
+
+ }
+}
diff --git a/Core/Eisk.Core/Exceptions/InvalidLookupIdParameterException.cs b/Core/Eisk.Core/Exceptions/InvalidLookupIdParameterException.cs
new file mode 100644
index 00000000..77f6e54d
--- /dev/null
+++ b/Core/Eisk.Core/Exceptions/InvalidLookupIdParameterException.cs
@@ -0,0 +1,10 @@
+namespace Eisk.Core.Exceptions;
+
+public class InvalidLookupIdParameterException : DomainException
+{
+ public InvalidLookupIdParameterException(string paramName = "id") : base(
+ $"Invalid lookup parameter: {paramName} to find {typeof(TEntity).Name}.", "APP-DATA-ERROR-001")
+ {
+
+ }
+}
diff --git a/Core/Eisk.Core/Exceptions/NonExistantEntityException.cs b/Core/Eisk.Core/Exceptions/NonExistantEntityException.cs
new file mode 100644
index 00000000..37e76f25
--- /dev/null
+++ b/Core/Eisk.Core/Exceptions/NonExistantEntityException.cs
@@ -0,0 +1,11 @@
+namespace Eisk.Core.Exceptions;
+
+public class NonExistantEntityException : DomainException
+
+{
+ public NonExistantEntityException(object paramValue, string paramName = "id") : base(
+ $"No {typeof(TEntity).Name} exists for given id {paramValue} for parameter {paramName}.", "APP-DATA-ERROR-002")
+ {
+
+ }
+}
diff --git a/Core/Eisk.Core/Exceptions/NullInputEntityException.cs b/Core/Eisk.Core/Exceptions/NullInputEntityException.cs
new file mode 100644
index 00000000..796c5062
--- /dev/null
+++ b/Core/Eisk.Core/Exceptions/NullInputEntityException.cs
@@ -0,0 +1,9 @@
+namespace Eisk.Core.Exceptions;
+
+public class NullInputEntityException : DomainException
+{
+ public NullInputEntityException() : base("Input object to be created or updated is null.", "APP-DATA-ERROR-003")
+ {
+
+ }
+}
diff --git a/Core/Eisk.Core/Exceptions/UpdatingIdIsNotSupported.cs b/Core/Eisk.Core/Exceptions/UpdatingIdIsNotSupported.cs
new file mode 100644
index 00000000..98676b78
--- /dev/null
+++ b/Core/Eisk.Core/Exceptions/UpdatingIdIsNotSupported.cs
@@ -0,0 +1,11 @@
+namespace Eisk.Core.Exceptions;
+
+public class UpdatingIdIsNotSupported : DomainException
+
+{
+ public UpdatingIdIsNotSupported(object paramValue, string paramName = "id") : base(
+ $"Updating {typeof(TEntity).Name} field {paramName} is not supported. Provided value: {paramValue}.", "APP-DATA-ERROR-004")
+ {
+
+ }
+}
diff --git a/Core/Eisk.Core/Utils/ExceptionThrower.cs b/Core/Eisk.Core/Utils/ExceptionThrower.cs
new file mode 100644
index 00000000..930bbab0
--- /dev/null
+++ b/Core/Eisk.Core/Utils/ExceptionThrower.cs
@@ -0,0 +1,13 @@
+namespace Eisk.Core.Utils;
+
+using Exceptions;
+
+public class ExceptionThrower
+{
+
+ public static void Throws()
+ where T : CoreException, new()
+ {
+ throw new T();
+ }
+}
diff --git a/Core/Eisk.Core/Utils/ExpressionUtil.cs b/Core/Eisk.Core/Utils/ExpressionUtil.cs
new file mode 100644
index 00000000..7feb8b64
--- /dev/null
+++ b/Core/Eisk.Core/Utils/ExpressionUtil.cs
@@ -0,0 +1,35 @@
+using System;
+using System.Linq.Expressions;
+using System.Reflection;
+
+namespace Eisk.Core.Utils;
+
+using Exceptions;
+
+public static class ExpressionUtil
+{
+ public static object GetPropertyValue(Expression> expression, TDomain data)
+ {
+ if (data == null)
+ throw new NullInputEntityException();
+
+ var prop = GetPropertyInfo(expression);
+ var value = prop.GetValue(data);
+ return value;
+ }
+
+ public static void SetPropertyValue(Expression> expression, TDomain data, object value)
+ {
+ if (data == null)
+ throw new NullInputEntityException();
+
+ var prop = GetPropertyInfo(expression);
+ prop.SetValue(data, value);
+ }
+
+ public static PropertyInfo GetPropertyInfo(Expression> expression)
+ {
+ var expr = (MemberExpression)expression.Body;
+ return (PropertyInfo)expr.Member;
+ }
+}
diff --git a/Core/Eisk.Core/Utils/ObjectExtensions.cs b/Core/Eisk.Core/Utils/ObjectExtensions.cs
new file mode 100644
index 00000000..61acfc65
--- /dev/null
+++ b/Core/Eisk.Core/Utils/ObjectExtensions.cs
@@ -0,0 +1,12 @@
+namespace Eisk.Core.Utils;
+
+public static class ObjectExtensions
+{
+ public static bool IsNullOrEmpty(this T value)
+ {
+ if (typeof(T) == typeof(string))
+ return string.IsNullOrEmpty(value as string);
+
+ return value == null || value.Equals(default(T));
+ }
+}
diff --git a/Core/Eisk.Core/Utils/UriAttribute.cs b/Core/Eisk.Core/Utils/UriAttribute.cs
new file mode 100644
index 00000000..7e426317
--- /dev/null
+++ b/Core/Eisk.Core/Utils/UriAttribute.cs
@@ -0,0 +1,25 @@
+using System;
+using System.ComponentModel.DataAnnotations;
+
+namespace Eisk.Core.Utils;
+
+public class UriAttribute : ValidationAttribute
+{
+ protected override ValidationResult IsValid(object value, ValidationContext validationContext)
+ {
+ if (value != null)
+ {
+ try
+ {
+ // ReSharper disable once ObjectCreationAsStatement
+ new Uri(value.ToString());
+ }
+ catch (Exception ex)
+ {
+ return new ValidationResult(ex.Message);
+ }
+ }
+ return ValidationResult.Success;
+ }
+
+}
diff --git a/Core/Eisk.Core/WebApi/WebApiControllerBase.cs b/Core/Eisk.Core/WebApi/WebApiControllerBase.cs
new file mode 100644
index 00000000..d605a1ba
--- /dev/null
+++ b/Core/Eisk.Core/WebApi/WebApiControllerBase.cs
@@ -0,0 +1,48 @@
+using Eisk.Core.DomainService;
+using Microsoft.AspNetCore.Mvc;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+
+namespace Eisk.Core.WebApi;
+
+[ApiController]
+[Route("api/[controller]")]
+public abstract class WebApiControllerBase : ControllerBase
+ where TDomain : class, new()
+{
+ protected DomainService DomainService;
+ protected WebApiControllerBase(DomainService domainService)
+ {
+ DomainService = domainService;
+ }
+
+ [HttpGet]
+ public virtual async Task> Get()
+ {
+ return await DomainService.GetAll();
+ }
+
+ [HttpGet("{id}")]
+ public virtual async Task Get(TId id)
+ {
+ return await DomainService.GetById(id);
+ }
+
+ [HttpPost]
+ public virtual async Task Post(TDomain domain)
+ {
+ await DomainService.Add(domain);
+ }
+
+ [HttpPut("{id}")]
+ public virtual async Task Put(TId id, TDomain domain)
+ {
+ await DomainService.Update(id, domain);
+ }
+
+ [HttpDelete("{id}")]
+ public virtual async Task Delete(TId id)
+ {
+ await DomainService.Delete(id);
+ }
+}
diff --git a/Core/Eisk.Test.Core.Tests/Eisk.Test.Core.Tests.csproj b/Core/Eisk.Test.Core.Tests/Eisk.Test.Core.Tests.csproj
new file mode 100644
index 00000000..863e45ad
--- /dev/null
+++ b/Core/Eisk.Test.Core.Tests/Eisk.Test.Core.Tests.csproj
@@ -0,0 +1,22 @@
+
+
+
+ net6.0
+
+ false
+
+
+
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
+
+
+
+
+
diff --git a/Core/Eisk.Test.Core.Tests/UnitTest1.cs b/Core/Eisk.Test.Core.Tests/UnitTest1.cs
new file mode 100644
index 00000000..6f77f38c
--- /dev/null
+++ b/Core/Eisk.Test.Core.Tests/UnitTest1.cs
@@ -0,0 +1,12 @@
+using Xunit;
+
+namespace Eisk.Test.Core.Tests;
+
+public class UnitTest1
+{
+ [Fact]
+ public void Test1()
+ {
+ //test- update from submodule .. more update
+ }
+}
diff --git a/Core/Eisk.Test.Core/DataGen/DataFactories/EntityDataFactory.cs b/Core/Eisk.Test.Core/DataGen/DataFactories/EntityDataFactory.cs
new file mode 100644
index 00000000..06d5cf2a
--- /dev/null
+++ b/Core/Eisk.Test.Core/DataGen/DataFactories/EntityDataFactory.cs
@@ -0,0 +1,36 @@
+using AutoFixture;
+using AutoFixture.DataAnnotations;
+using System;
+
+namespace Eisk.Test.Core.DataGen.DataFactories;
+
+public class EntityDataFactory
+{
+ public virtual TEntity Factory_Entity(Action action = null)
+ {
+ var fixture = Factory_Fixture();
+
+ var obj = fixture.Create();
+
+ action?.Invoke(obj);
+
+ return obj;
+ }
+
+ private Fixture Factory_Fixture()
+ {
+ Fixture fixture = new Fixture();
+
+ fixture.Behaviors.Remove(new ThrowingRecursionBehavior());
+
+ fixture.Behaviors.Add(new OmitOnRecursionBehavior());
+
+ fixture.Customize(new NoDataAnnotationsCustomization());
+
+ fixture.Customizations.Add(new RangeAttributeRelay());
+
+ fixture.Customizations.Add(new StringAttributeAggregatedRelay());
+
+ return fixture;
+ }
+}
diff --git a/Core/Eisk.Test.Core/DataGen/DataFactories/EntityDomainDataFactory.cs b/Core/Eisk.Test.Core/DataGen/DataFactories/EntityDomainDataFactory.cs
new file mode 100644
index 00000000..0f10d475
--- /dev/null
+++ b/Core/Eisk.Test.Core/DataGen/DataFactories/EntityDomainDataFactory.cs
@@ -0,0 +1,21 @@
+using System;
+
+namespace Eisk.Test.Core.DataGen.DataFactories;
+
+public abstract class EntityDomainDataFactory : EntityDataFactory
+{
+ public override TEntity Factory_Entity(Action action = null)
+ {
+ var entity = base.Factory_Entity(e =>
+ {
+ AssignDomainData(e);
+
+ //supporting custom overrides from user
+ action?.Invoke(e);
+ });
+
+ return entity;
+ }
+
+ protected abstract void AssignDomainData(TEntity e);
+}
diff --git a/Core/Eisk.Test.Core/DataGen/FieldGenerators/DomainUriGenerator.cs b/Core/Eisk.Test.Core/DataGen/FieldGenerators/DomainUriGenerator.cs
new file mode 100644
index 00000000..7ea3f1fa
--- /dev/null
+++ b/Core/Eisk.Test.Core/DataGen/FieldGenerators/DomainUriGenerator.cs
@@ -0,0 +1,66 @@
+using AutoFixture;
+using AutoFixture.Kernel;
+using System;
+
+namespace Eisk.Test.Core.DataGen.FieldGenerators;
+
+///
+/// Creates new instances.
+///
+public class DomainUriGenerator
+{
+ private readonly int _minSize, _maxSize;
+ private readonly bool _appendPath;
+
+ public DomainUriGenerator(int minSize = 1, int maxSize = int.MaxValue, bool appendPath = true)
+ {
+ _minSize = minSize;
+ _maxSize = maxSize;
+ _appendPath = appendPath;
+ }
+
+ ///
+ /// Creates a new specimen based on a request.
+ ///
+ /// The request that describes what to create.
+ /// A context that can be used to create other specimens.
+ ///
+ /// The requested specimen if possible; otherwise a instance.
+ ///
+ public object Create(object request, ISpecimenContext context)
+ {
+ if (context == null)
+ {
+ throw new ArgumentNullException(nameof(context));
+ }
+
+ if (!typeof(Uri).Equals(request))
+ {
+#pragma warning disable 618
+ return new NoSpecimen();
+#pragma warning restore 618
+ }
+
+ var scheme = context.Resolve(typeof(UriScheme)) as UriScheme;
+ if (scheme == null)
+ {
+#pragma warning disable 618
+ return new NoSpecimen();
+#pragma warning restore 618
+ }
+
+ return CreateUri(scheme, context);
+ }
+
+ private Uri CreateUri(UriScheme scheme, ISpecimenContext context)
+ {
+ string suffix = string.Empty;
+
+ ConstrainedStringRequest constrainedStringRequest = new ConstrainedStringRequest(_minSize, _maxSize);
+
+ if (_appendPath)
+ suffix = "/" + context.Resolve(constrainedStringRequest);
+
+ return new Uri(scheme + "://google.com/" + suffix);//TODO: support maxsize constraint
+ }
+}
diff --git a/Core/Eisk.Test.Core/DataGen/FieldGenerators/IntegerValueGenerator.cs b/Core/Eisk.Test.Core/DataGen/FieldGenerators/IntegerValueGenerator.cs
new file mode 100644
index 00000000..9ca5c984
--- /dev/null
+++ b/Core/Eisk.Test.Core/DataGen/FieldGenerators/IntegerValueGenerator.cs
@@ -0,0 +1,20 @@
+using System;
+
+namespace Eisk.Test.Core.DataGen.FieldGenerators;
+
+public class IntegerValueGenerator
+{
+ private readonly int _maxValue;
+
+ public IntegerValueGenerator(int maxValue = Int32.MaxValue)
+ {
+ _maxValue = maxValue;
+ }
+
+ public int Value()
+ {
+ return new Random().Next(1, _maxValue);
+ }
+
+ public static int RandomInt => new IntegerValueGenerator().Value();
+}
diff --git a/Core/Eisk.Test.Core/DataGen/FieldGenerators/StringValueGenerator.cs b/Core/Eisk.Test.Core/DataGen/FieldGenerators/StringValueGenerator.cs
new file mode 100644
index 00000000..3b0a9685
--- /dev/null
+++ b/Core/Eisk.Test.Core/DataGen/FieldGenerators/StringValueGenerator.cs
@@ -0,0 +1,20 @@
+using System;
+
+namespace Eisk.Test.Core.DataGen.FieldGenerators;
+
+public class StringValueGenerator
+{
+ private readonly string _seedValue;
+ private readonly bool _generateUniqueValue;
+
+ public StringValueGenerator(bool generateUniqueValue, string seedValue)
+ {
+ _seedValue = seedValue;
+ _generateUniqueValue = generateUniqueValue;
+ }
+
+ public override string ToString()
+ {
+ return !_generateUniqueValue ? _seedValue : _seedValue + "_" + Guid.NewGuid();
+ }
+}
diff --git a/Core/Eisk.Test.Core/DataGen/InvalidData/Get.cs b/Core/Eisk.Test.Core/DataGen/InvalidData/Get.cs
new file mode 100644
index 00000000..ae4d515d
--- /dev/null
+++ b/Core/Eisk.Test.Core/DataGen/InvalidData/Get.cs
@@ -0,0 +1,23 @@
+namespace Eisk.Test.Core.DataGen.InvalidData;
+
+public class Get
+{
+ private readonly bool _generateUniqueValue;
+
+ public Get(bool generateUniqueValue)
+ {
+ _generateUniqueValue = generateUniqueValue;
+ }
+
+ public static Get Unique => new Get(true);
+
+ public static Get Plain => new Get(false);
+
+ public string InvalidEmail => new InvalidEmail(_generateUniqueValue).ToString();
+
+ public string InvalidUri => new InvalidUri(_generateUniqueValue).ToString();
+
+ public string InvalidAlphanumeric => new InvalidAlphanumeric(_generateUniqueValue).ToString();
+
+ public string StringWithSpecialCharacters => new StringWithSpecialCharacters(_generateUniqueValue).ToString();
+}
diff --git a/Core/Eisk.Test.Core/DataGen/InvalidData/InvalidAlphanumeric.cs b/Core/Eisk.Test.Core/DataGen/InvalidData/InvalidAlphanumeric.cs
new file mode 100644
index 00000000..53902b4c
--- /dev/null
+++ b/Core/Eisk.Test.Core/DataGen/InvalidData/InvalidAlphanumeric.cs
@@ -0,0 +1,11 @@
+namespace Eisk.Test.Core.DataGen.InvalidData;
+
+using FieldGenerators;
+
+public class InvalidAlphanumeric : StringValueGenerator
+{
+ public InvalidAlphanumeric(bool generateUniqueValue = true, string value = "invalid_alphanumeric") : base(generateUniqueValue, value)
+ {
+
+ }
+}
diff --git a/Core/Eisk.Test.Core/DataGen/InvalidData/InvalidEmail.cs b/Core/Eisk.Test.Core/DataGen/InvalidData/InvalidEmail.cs
new file mode 100644
index 00000000..f53ea96e
--- /dev/null
+++ b/Core/Eisk.Test.Core/DataGen/InvalidData/InvalidEmail.cs
@@ -0,0 +1,11 @@
+namespace Eisk.Test.Core.DataGen.InvalidData;
+
+using FieldGenerators;
+
+public class InvalidEmail : StringValueGenerator
+{
+ public InvalidEmail(bool generateUniqueValue = true, string value = "invalid_email") : base(generateUniqueValue, value)
+ {
+
+ }
+}
diff --git a/Core/Eisk.Test.Core/DataGen/InvalidData/InvalidUri.cs b/Core/Eisk.Test.Core/DataGen/InvalidData/InvalidUri.cs
new file mode 100644
index 00000000..b76deb26
--- /dev/null
+++ b/Core/Eisk.Test.Core/DataGen/InvalidData/InvalidUri.cs
@@ -0,0 +1,11 @@
+namespace Eisk.Test.Core.DataGen.InvalidData;
+
+using FieldGenerators;
+
+public class InvalidUri : StringValueGenerator
+{
+ public InvalidUri(bool generateUniqueValue = true, string value = "invalid_uri") : base(generateUniqueValue, value)
+ {
+
+ }
+}
diff --git a/Core/Eisk.Test.Core/DataGen/InvalidData/StringWithSpecialCharacters.cs b/Core/Eisk.Test.Core/DataGen/InvalidData/StringWithSpecialCharacters.cs
new file mode 100644
index 00000000..6e66dec9
--- /dev/null
+++ b/Core/Eisk.Test.Core/DataGen/InvalidData/StringWithSpecialCharacters.cs
@@ -0,0 +1,8 @@
+namespace Eisk.Test.Core.DataGen.InvalidData;
+
+using FieldGenerators;
+
+public class StringWithSpecialCharacters : StringValueGenerator
+{
+ public StringWithSpecialCharacters(bool generateUniqueValie = true, string value = "@@@@###%%%_string_with_special_characters") : base(generateUniqueValie, value) { }
+}
diff --git a/Core/Eisk.Test.Core/DataGen/StringAttributeAggregatedRelay.cs b/Core/Eisk.Test.Core/DataGen/StringAttributeAggregatedRelay.cs
new file mode 100644
index 00000000..638bb178
--- /dev/null
+++ b/Core/Eisk.Test.Core/DataGen/StringAttributeAggregatedRelay.cs
@@ -0,0 +1,59 @@
+using AutoFixture.Kernel;
+using Eisk.Core.Utils;
+using Eisk.Test.Core.DataGen.FieldGenerators;
+using System;
+using System.ComponentModel.DataAnnotations;
+using System.Linq;
+using System.Reflection;
+
+namespace Eisk.Test.Core.DataGen;
+
+public class StringAttributeAggregatedRelay : ISpecimenBuilder
+{
+ public object Create(object request, ISpecimenContext context)
+ {
+
+#pragma warning disable 618
+ object result = new NoSpecimen();
+#pragma warning restore 618
+
+ var pi = request as PropertyInfo;
+
+ if (pi != null)
+ {
+ if (pi.PropertyType == typeof(string))
+ {
+ if (Attribute.IsDefined(pi, typeof(StringLengthAttribute)))
+ {
+ var stringLengthAttribute = ((ICustomAttributeProvider)request).
+ GetCustomAttributes(typeof(StringLengthAttribute), true)
+ .Cast().Single();
+
+ return Attribute.IsDefined(pi, typeof(UrlAttribute)) || Attribute.IsDefined(pi, typeof(UriAttribute))
+ ? GetGeneratedUri(context, stringLengthAttribute.MinimumLength,
+ stringLengthAttribute.MaximumLength)
+ : context.Resolve(new ConstrainedStringRequest(
+ stringLengthAttribute.MinimumLength,
+ stringLengthAttribute.MaximumLength));
+ }
+
+ if (Attribute.IsDefined(pi, typeof(UrlAttribute)))
+ {
+ return GetGeneratedUri(context);
+ }
+ }
+
+ return result;
+ }
+
+ return result;
+ }
+
+ private string GetGeneratedUri(ISpecimenContext context, int minLength = 1, int maxLength = int.MaxValue)
+ {
+ var generatedUri = new DomainUriGenerator(minLength, maxLength)
+ .Create(typeof(Uri), context);
+ return generatedUri.ToString();
+ }
+
+}
diff --git a/Core/Eisk.Test.Core/Eisk.Test.Core.csproj b/Core/Eisk.Test.Core/Eisk.Test.Core.csproj
new file mode 100644
index 00000000..5780595d
--- /dev/null
+++ b/Core/Eisk.Test.Core/Eisk.Test.Core.csproj
@@ -0,0 +1,17 @@
+
+
+
+ net6.0
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Core/Eisk.Test.Core/TestBases/DataServiceBaseIntegrationTests.cs b/Core/Eisk.Test.Core/TestBases/DataServiceBaseIntegrationTests.cs
new file mode 100644
index 00000000..42527221
--- /dev/null
+++ b/Core/Eisk.Test.Core/TestBases/DataServiceBaseIntegrationTests.cs
@@ -0,0 +1,212 @@
+using Eisk.Core.DataService;
+using Eisk.Test.Core.DataGen.DataFactories;
+using System;
+using System.Linq.Expressions;
+using System.Threading.Tasks;
+using Xunit;
+
+namespace Eisk.Test.Core.TestBases;
+
+public abstract class DataServiceBaseIntegrationTests : EntityTestBase,
+ IServiceTest>
+ where TEntity : class, new()
+{
+ private readonly IEntityDataService _dataService;
+
+ protected DataServiceBaseIntegrationTests(IEntityDataService dataService, Expression> idExpression, EntityDataFactory entityDataFactory = null)
+ : base(idExpression, entityDataFactory)
+ {
+ _dataService = dataService;
+ }
+
+
+ public virtual IEntityDataService GetServiceInstance(Action action = null)
+ {
+ action?.Invoke();
+
+ return _dataService;
+ }
+
+ protected virtual async Task CreateTestEntityToStore(TEntity testEntity)
+ {
+ await _dataService.Add(testEntity);
+ }
+
+ [Fact]
+ public virtual async Task Add_ValidDomainPassed_ShouldReturnDomainAfterCreation()
+ {
+ //Arrange
+ var inputEntity = Factory_Entity();
+ var dataService = GetServiceInstance();
+
+ //Act
+ var returnedEntity = await dataService.Add(inputEntity);
+
+ //Assert
+ Assert.NotNull(returnedEntity);
+ Assert.NotEqual(default(TId), GetIdValueFromEntity(returnedEntity));
+ }
+
+ [Fact]
+ public virtual async Task Add_NullDomainPassed_ShouldThrowArgumentNullException()
+ {
+ //Arrange
+ var dataService = GetServiceInstance();
+ TEntity invalidNullDomain = null;
+
+ //Act and Assert
+ await Assert.ThrowsAsync(() => dataService.Add(invalidNullDomain));
+
+ }
+
+ [Fact]
+ public virtual async Task GetById_ValidIdPassed_ShouldReturnResult()
+ {
+ //Arrange
+ var domain = Factory_Entity();
+ var dataService = GetServiceInstance();
+ await CreateTestEntityToStore(domain);
+
+ var idValue = GetIdValueFromEntity(domain);
+
+ //Act
+ var returnedEntity = await dataService.GetById(idValue);
+
+ //Assert
+ Assert.NotNull(returnedEntity);
+ Assert.Equal(idValue, GetIdValueFromEntity(returnedEntity));
+ }
+
+ [Fact]
+ public virtual async Task GetById_EmptyIdPassed_ShouldReturnNull()
+ {
+ //Arrange
+ var dataService = GetServiceInstance();
+
+ //Act
+ var returnedEntity = await dataService.GetById(default(TId));
+
+ //Assert
+ Assert.Null(returnedEntity);
+
+ }
+
+ [Fact]
+ public virtual async Task GetById_InvalidIdPassed_ShouldReturnNull()
+ {
+ //Arrange
+ var dataService = GetServiceInstance();
+
+ //Act
+ var returnedEntity = await dataService.GetById(RANDOM_ID);//TODO: make it generic random
+
+ //Assert
+ Assert.Null(returnedEntity);
+
+ }
+
+ [Fact]
+ public virtual async Task Update_ValidDomainPassed_ShouldReturnDomain()
+ {
+ //Arrange
+ var inputEntity = Factory_Entity();
+ var dataService = GetServiceInstance();
+ await CreateTestEntityToStore(inputEntity);
+
+ //Act
+ var returnedEntity = await dataService.Update(inputEntity);
+
+ //Assert
+ Assert.NotNull(returnedEntity);
+ Assert.Equal(GetIdValueFromEntity(inputEntity), GetIdValueFromEntity(returnedEntity));
+
+ }
+
+ [Fact]
+ public virtual async Task Update_ValidDomainWithEmptyIdPassed_ShouldCreateDomain()
+ {
+ //Arrange
+ var inputEntity = Factory_Entity();
+ var dataService = GetServiceInstance();
+
+ //Act
+ var returnedEntity = await dataService.Update(inputEntity);//may not be supported in all data providers
+
+ //Assert
+ Assert.NotNull(returnedEntity);
+ Assert.NotEqual(default(TId), GetIdValueFromEntity(returnedEntity));
+
+ }
+
+ [Fact]
+ public virtual async Task Update_ValidDomainWithRandomIdPassed_ShouldThrowException()
+ {
+ //Arrange
+ var entityWithRandomId = Factory_EntityWithRandomId();
+
+ var dataService = GetServiceInstance();
+
+ //Act
+ var ex = await Record.ExceptionAsync(async () => await dataService.Update(entityWithRandomId));
+
+ //Assert
+ Assert.NotNull(ex);
+ }
+
+ [Fact]
+ public virtual async Task Update_NullDomainPassed_ShouldThrowArgumentNullException()
+ {
+ //Arrange
+ var dataService = GetServiceInstance();
+ TEntity invalidNullDomain = null;
+
+ //Act and Assert
+ await Assert.ThrowsAsync(() => dataService.Update(invalidNullDomain));
+
+ }
+
+ [Fact]
+ public virtual async Task Delete_DomainWithValidIdPassed_ShouldDeleteSuccessfully()
+ {
+ //Arrange
+ var inputEntity = Factory_Entity();
+ var dataService = GetServiceInstance();
+ await CreateTestEntityToStore(inputEntity);
+ var idValue = GetIdValueFromEntity(inputEntity);
+
+ //Act
+ await dataService.Delete(inputEntity);
+
+ //Assert
+ var returnObject = await dataService.GetById(idValue);
+ Assert.Null(returnObject);
+ }
+
+ [Fact]
+ public virtual async Task Delete_DomainWithEmptyIdPassed_ShouldThrowException()
+ {
+ //Arrange
+ var inputEntity = Factory_Entity();
+ var dataService = GetServiceInstance();
+
+ //Act
+ var returnedException = await Record.ExceptionAsync(() => dataService.Delete(inputEntity));
+
+ //Assert
+ Assert.NotNull(returnedException);
+ }
+
+ [Fact]
+ public virtual async Task Delete_DomainWithRandomIdPassed_ShouldThrowException()
+ {
+ //Arrange
+ var inputEntity = Factory_EntityWithRandomId();
+ var dataService = GetServiceInstance();
+
+ //Act
+ var ex = await Record.ExceptionAsync(() => dataService.Delete(inputEntity));
+
+ //Assert
+ Assert.NotNull(ex);
+ }
+}
diff --git a/Core/Eisk.Test.Core/TestBases/DataServiceSqlServerBaseIntegrationTests.cs b/Core/Eisk.Test.Core/TestBases/DataServiceSqlServerBaseIntegrationTests.cs
new file mode 100644
index 00000000..a46ffaf1
--- /dev/null
+++ b/Core/Eisk.Test.Core/TestBases/DataServiceSqlServerBaseIntegrationTests.cs
@@ -0,0 +1,32 @@
+using Eisk.Core.DataService;
+using Eisk.Test.Core.DataGen.DataFactories;
+using Microsoft.EntityFrameworkCore;
+using System;
+using System.Linq.Expressions;
+using System.Threading.Tasks;
+using Xunit;
+
+namespace Eisk.Test.Core.TestBases;
+
+public abstract class DataServiceSqlServerBaseIntegrationTests : DataServiceBaseIntegrationTests,
+ IServiceTest>
+ where TEntity : class, new()
+{
+ protected DataServiceSqlServerBaseIntegrationTests(IEntityDataService dataService, Expression> idExpression, EntityDataFactory entityDataFactory = null)
+ : base(dataService, idExpression, entityDataFactory)
+ {
+
+ }
+
+
+ [Fact]
+ public virtual async Task Add_ValidDomainWithRandomIdPassed_ShouldThrowException()
+ {
+ //Arrange
+ var inputEntityWithRandomId = Factory_EntityWithRandomId();
+ var dataService = GetServiceInstance();
+
+ //Assert
+ await Assert.ThrowsAsync(() => dataService.Add(inputEntityWithRandomId));
+ }
+}
diff --git a/Core/Eisk.Test.Core/TestBases/DomainServiceBaseComponentTests.cs b/Core/Eisk.Test.Core/TestBases/DomainServiceBaseComponentTests.cs
new file mode 100644
index 00000000..3c503311
--- /dev/null
+++ b/Core/Eisk.Test.Core/TestBases/DomainServiceBaseComponentTests.cs
@@ -0,0 +1,151 @@
+using Eisk.Core.DomainService;
+using Eisk.Core.Exceptions;
+using Eisk.Test.Core.DataGen.DataFactories;
+using System;
+using System.Linq.Expressions;
+using System.Threading.Tasks;
+using Xunit;
+
+namespace Eisk.Test.Core.TestBases;
+
+public abstract class DomainServiceBaseComponentTests : EntityTestBase,
+ IServiceTest>
+ where TEntity : class, new()
+{
+ private readonly DomainService _domainService;
+
+ protected DomainServiceBaseComponentTests(DomainService domainService,
+ Expression> idExpression, EntityDataFactory entityDataFactory) : base(idExpression, entityDataFactory)
+ {
+ _domainService = domainService;
+ }
+
+ public virtual DomainService GetServiceInstance(Action action = null)
+ {
+ action?.Invoke();
+
+ return _domainService;
+ }
+
+ protected virtual async Task CreateTestEntityToStore(TEntity testEntity)
+ {
+ await _domainService.Add(testEntity);
+ }
+
+ [Fact]
+ public virtual async Task Add_ValidDomainPassed_ShouldReturnDomainAfterCreation()
+ {
+ //Arrange
+ var inputEntity = Factory_Entity();
+ var domainService = GetServiceInstance();
+
+ //Act
+ var returnedEntity = await domainService.Add(inputEntity);
+
+ //Assert
+ Assert.NotNull(returnedEntity);
+ Assert.NotEqual(default(TId), GetIdValueFromEntity(returnedEntity));
+ }
+
+ [Fact]
+ public virtual async Task Add_NullDomainPassed_ShouldThrowArgumentNullException()
+ {
+ //Arrange
+ var domainService = GetServiceInstance();
+ TEntity invalidNullDomain = null;
+
+ //Act and Assert
+ await Assert.ThrowsAsync>(() => domainService.Add(invalidNullDomain));
+
+ }
+
+ [Fact]
+ public virtual async Task GetById_ValidIdPassed_ShouldReturnResult()
+ {
+ //Arrange
+ var domain = Factory_Entity();
+ var domainService = GetServiceInstance(async () =>
+ {
+ await CreateTestEntityToStore(domain);
+ });
+
+ var idValue = GetIdValueFromEntity(domain);
+
+ //Act
+ var returnedEntity = await domainService.GetById(idValue);
+
+ //Assert
+ Assert.NotNull(returnedEntity);
+ Assert.Equal(idValue, GetIdValueFromEntity(returnedEntity));
+ }
+
+ [Fact]
+ public virtual async Task GetById_EmptyIdPassed_ShouldThrowException()
+ {
+ //Arrange
+ var domainService = GetServiceInstance();
+ var emptyIdValue = default(TId);
+
+ //Act + Assert
+ await Assert.ThrowsAsync>(() => domainService.GetById(emptyIdValue));
+
+ }
+
+ [Fact]
+ public virtual async Task Update_ValidDomainPassed_ShouldReturnDomain()
+ {
+ //Arrange
+ var inputEntity = Factory_Entity();
+ var domainService = GetServiceInstance(async () =>
+ {
+ await CreateTestEntityToStore(inputEntity);
+ });
+ var idValue = GetIdValueFromEntity(inputEntity);
+
+ //Act
+ var returnedEntity = await domainService.Update(idValue, inputEntity);
+
+ //Assert
+ Assert.NotNull(returnedEntity);
+ Assert.Equal(GetIdValueFromEntity(inputEntity), GetIdValueFromEntity(returnedEntity));
+
+ }
+
+ [Fact]
+ public virtual async Task Update_EmptyIdPassed_ShouldThrowException()
+ {
+ //Arrange
+ var domainService = GetServiceInstance();
+ var emptyIdValue = default(TId);
+ TEntity dummayObject = Factory_Entity();
+
+ //Act + Assert
+ await Assert.ThrowsAsync>(() => domainService.Update(emptyIdValue, dummayObject));
+
+ }
+
+ [Fact]
+ public virtual async Task Delete_DomainWithValidIdPassed_ShouldDeleteSuccessfully()
+ {
+ //Arrange
+ var inputEntity = Factory_Entity();
+ var domainService = GetServiceInstance(async () => await CreateTestEntityToStore(inputEntity));
+ var idValue = GetIdValueFromEntity(inputEntity);
+
+ //Act + Assert
+ await domainService.Delete(idValue);
+
+ }
+
+ [Fact]
+ public virtual async Task Delete_DomainWithEmptyIdPassed_ShouldThrowException()
+ {
+ //Arrange
+ var domainService = GetServiceInstance();
+ var emptyIdValue = default(TId);
+
+ //Act + Assert
+ await Assert.ThrowsAsync>(() => domainService.Delete(emptyIdValue));
+
+ }
+}
diff --git a/Core/Eisk.Test.Core/TestBases/EntityTestBase.cs b/Core/Eisk.Test.Core/TestBases/EntityTestBase.cs
new file mode 100644
index 00000000..25c709ce
--- /dev/null
+++ b/Core/Eisk.Test.Core/TestBases/EntityTestBase.cs
@@ -0,0 +1,62 @@
+using Eisk.Core.Utils;
+using Eisk.Test.Core.DataGen.DataFactories;
+using System;
+using System.Linq.Expressions;
+
+namespace Eisk.Test.Core.TestBases;
+
+public abstract class EntityTestBase : TestBase
+ where TEntity : class, new()
+{
+ protected readonly Expression> DbIdExpression;
+
+ EntityDataFactory _entityDataFactory;
+ protected EntityDataFactory EntityDataFactory
+ {
+ get
+ {
+ if (_entityDataFactory == null)
+ _entityDataFactory = new EntityDataFactory();
+
+ return _entityDataFactory; ;
+ }
+ }
+
+ protected const int RANDOM_ID = 10000;
+ protected EntityTestBase(Expression> idExpression, EntityDataFactory entityDataFactory = null)
+ {
+ DbIdExpression = idExpression;
+ _entityDataFactory = entityDataFactory;
+ }
+
+ protected virtual TEntity Factory_Entity(Action action = null, bool setIdWithDefault = true)
+ {
+ var entity = EntityDataFactory.Factory_Entity(action);
+
+ if (setIdWithDefault)
+ SetIdValueToEntity(entity, default(TId));
+
+ action?.Invoke(entity);
+
+ return entity;
+ }
+
+ protected virtual TEntity Factory_EntityWithRandomId(Action action = null)
+ {
+ var entity = Factory_Entity(action, false);
+
+ SetIdValueToEntity(entity, RANDOM_ID);//TODO: to be randomize
+
+ return entity;
+ }
+
+ protected TId GetIdValueFromEntity(TEntity entity)
+ {
+ return (TId)ExpressionUtil.GetPropertyValue(DbIdExpression, entity);
+ }
+
+ protected void SetIdValueToEntity(TEntity entity, object value)
+ {
+ ExpressionUtil.SetPropertyValue(DbIdExpression, entity, value);
+ }
+}
diff --git a/Core/Eisk.Test.Core/TestBases/IServiceTest.cs b/Core/Eisk.Test.Core/TestBases/IServiceTest.cs
new file mode 100644
index 00000000..ef475bef
--- /dev/null
+++ b/Core/Eisk.Test.Core/TestBases/IServiceTest.cs
@@ -0,0 +1,8 @@
+using System;
+
+namespace Eisk.Test.Core.TestBases;
+
+public interface IServiceTest
+{
+ TService GetServiceInstance(Action action = null);
+}
diff --git a/Core/Eisk.Test.Core/TestBases/TestBase.cs b/Core/Eisk.Test.Core/TestBases/TestBase.cs
new file mode 100644
index 00000000..770fdf85
--- /dev/null
+++ b/Core/Eisk.Test.Core/TestBases/TestBase.cs
@@ -0,0 +1,23 @@
+using System;
+using Xunit;
+
+namespace Eisk.Test.Core.TestBases;
+
+using Eisk.Core.Exceptions;
+
+public abstract class TestBase
+{
+ protected static void ExpectException(Action action,
+ TException expectedException)
+ where TException : CoreException
+ {
+ //Act
+ var actualException = Assert.Throws(action);
+
+ //Assert
+ Assert.NotNull(actualException);
+ Assert.Equal(expectedException.Message, actualException.Message);
+ Assert.Equal(expectedException.ErrorCode, actualException.ErrorCode);
+ }
+
+}
diff --git a/DomainCore/Eisk.DataServices.Interfaces/Eisk.DataServices.Interfaces.csproj b/DomainCore/Eisk.DataServices.Interfaces/Eisk.DataServices.Interfaces.csproj
index 84ba9322..e2b6d849 100644
--- a/DomainCore/Eisk.DataServices.Interfaces/Eisk.DataServices.Interfaces.csproj
+++ b/DomainCore/Eisk.DataServices.Interfaces/Eisk.DataServices.Interfaces.csproj
@@ -1,7 +1,7 @@
- netcoreapp2.0
+ net6.0
diff --git a/DomainCore/Eisk.DataServices.Interfaces/IEmployeeDataService.cs b/DomainCore/Eisk.DataServices.Interfaces/IEmployeeDataService.cs
index 9a8cbf4d..ae50e883 100644
--- a/DomainCore/Eisk.DataServices.Interfaces/IEmployeeDataService.cs
+++ b/DomainCore/Eisk.DataServices.Interfaces/IEmployeeDataService.cs
@@ -1,13 +1,13 @@
using System.Collections.Generic;
-using Eisk.Core.DataService;
using System.Threading.Tasks;
-using Eisk.Domains.Entities;
-namespace Eisk.DataServices.Interfaces
+namespace Eisk.DataServices.Interfaces;
+
+using Core.DataService;
+using Domains.Entities;
+
+public interface IEmployeeDataService : IEntityDataService
{
- public interface IEmployeeDataService: IEntityDataService
- {
- Task> GetByFirstName(string firstName);
+ Task> GetByFirstName(string firstName);
- }
-}
\ No newline at end of file
+}
diff --git a/DomainCore/Eisk.DomainServices.UnitTests/Eisk.DomainServices.UnitTests.csproj b/DomainCore/Eisk.DomainServices.UnitTests/Eisk.DomainServices.UnitTests.csproj
index d4cb5f75..1b14413c 100644
--- a/DomainCore/Eisk.DomainServices.UnitTests/Eisk.DomainServices.UnitTests.csproj
+++ b/DomainCore/Eisk.DomainServices.UnitTests/Eisk.DomainServices.UnitTests.csproj
@@ -1,14 +1,17 @@
- netcoreapp2.0
+ net6.0
-
-
-
-
+
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
diff --git a/DomainCore/Eisk.DomainServices.UnitTests/EmployeeDomainServiceUnitTests.cs b/DomainCore/Eisk.DomainServices.UnitTests/EmployeeDomainServiceUnitTests.cs
index cc530c43..c4d0c43b 100644
--- a/DomainCore/Eisk.DomainServices.UnitTests/EmployeeDomainServiceUnitTests.cs
+++ b/DomainCore/Eisk.DomainServices.UnitTests/EmployeeDomainServiceUnitTests.cs
@@ -2,39 +2,38 @@
using System.Threading.Tasks;
using Xunit;
-namespace Eisk.DomainServices.UnitTests
+namespace Eisk.DomainServices.UnitTests;
+
+using Core.Exceptions;
+using DataServices.Interfaces;
+using Domains.Entities;
+
+public class EmployeeDomainServiceUnitTests
{
- using Core.Exceptions;
- using DataServices.Interfaces;
- using Domains.Entities;
+ #region Helpers
- public class EmployeeDomainServiceUnitTests
+ static Mock Factory_DataService()
{
- #region Helpers
+ Mock employeeDataServiceMock = new Mock();
- static Mock Factory_DataService()
- {
- Mock employeeDataServiceMock = new Mock();
-
- return employeeDataServiceMock;
- }
+ return employeeDataServiceMock;
+ }
- static EmployeeDomainService Factory_DomainService()
- {
- return new EmployeeDomainService(Factory_DataService().Object) ;
- }
+ static EmployeeDomainService Factory_DomainService()
+ {
+ return new EmployeeDomainService(Factory_DataService().Object);
+ }
- #endregion
+ #endregion
- [Fact]
- public async Task Add_NullEmployeePassed_ShouldThrowExceptionAsync()
- {
- //Act + Assert
- var error = await Assert.ThrowsAsync>(testCode: () => Factory_DomainService().Add(null));
+ [Fact]
+ public async Task Add_NullEmployeePassed_ShouldThrowExceptionAsync()
+ {
+ //Act + Assert
+ var error = await Assert.ThrowsAsync>(testCode: () => Factory_DomainService().Add(null));
- //Assert
- Assert.Equal("Input object to be created or updated is null.", error.Message);
+ //Assert
+ Assert.Equal("Input object to be created or updated is null.", error.Message);
- }
}
}
diff --git a/DomainCore/Eisk.DomainServices/Eisk.DomainServices.csproj b/DomainCore/Eisk.DomainServices/Eisk.DomainServices.csproj
index 0ff487fd..744fadc1 100644
--- a/DomainCore/Eisk.DomainServices/Eisk.DomainServices.csproj
+++ b/DomainCore/Eisk.DomainServices/Eisk.DomainServices.csproj
@@ -1,7 +1,7 @@
- netcoreapp2.0
+ net6.0
diff --git a/DomainCore/Eisk.DomainServices/EmployeeDomainService.cs b/DomainCore/Eisk.DomainServices/EmployeeDomainService.cs
index 1df6f3c4..9df81695 100644
--- a/DomainCore/Eisk.DomainServices/EmployeeDomainService.cs
+++ b/DomainCore/Eisk.DomainServices/EmployeeDomainService.cs
@@ -1,24 +1,23 @@
using System.Collections.Generic;
using System.Threading.Tasks;
-namespace Eisk.DomainServices
-{
- using Core.DomainService;
- using DataServices.Interfaces;
- using Domains.Entities;
+namespace Eisk.DomainServices;
- public class EmployeeDomainService : DomainService
- {
- private readonly IEmployeeDataService _employeeDataService;
+using Core.DomainService;
+using DataServices.Interfaces;
+using Domains.Entities;
- public EmployeeDomainService(IEmployeeDataService employeeDataService) : base(employeeDataService)
- {
- _employeeDataService = employeeDataService;
- }
+public class EmployeeDomainService : DomainService
+{
+ private readonly IEmployeeDataService _employeeDataService;
- public virtual async Task> GetByFirstName(string firstName)
- {
- return await _employeeDataService.GetByFirstName(firstName);
- }
+ public EmployeeDomainService(IEmployeeDataService employeeDataService) : base(employeeDataService)
+ {
+ _employeeDataService = employeeDataService;
+ }
+ public virtual async Task> GetByFirstName(string firstName)
+ {
+ return await _employeeDataService.GetByFirstName(firstName);
}
-}
\ No newline at end of file
+
+}
diff --git a/DomainCore/Eisk.Domains.TestData/Eisk.Domains.TestData.csproj b/DomainCore/Eisk.Domains.TestData/Eisk.Domains.TestData.csproj
new file mode 100644
index 00000000..df4903a0
--- /dev/null
+++ b/DomainCore/Eisk.Domains.TestData/Eisk.Domains.TestData.csproj
@@ -0,0 +1,19 @@
+
+
+
+ net6.0
+ enable
+ enable
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/DomainCore/Eisk.Domains.TestData/EmployeeDataFactory.cs b/DomainCore/Eisk.Domains.TestData/EmployeeDataFactory.cs
new file mode 100644
index 00000000..f1ec5748
--- /dev/null
+++ b/DomainCore/Eisk.Domains.TestData/EmployeeDataFactory.cs
@@ -0,0 +1,46 @@
+using Bogus;
+
+namespace Eisk.Domains.TestData;
+
+using Eisk.Test.Core.DataGen.DataFactories;
+using Entities;
+using Enums;
+
+public class EmployeeDataFactory : EntityDomainDataFactory
+{
+ string[] _jobTitles = new string[] { "Vice President", "Director", "Manager", "Executive", "Sales Executive", "Management Trainee" };
+ protected override void AssignDomainData(Employee employee)
+ {
+ var faker = new Faker();
+
+ employee.Id = 0;
+ employee.ReportsTo = null;
+ employee.ReportsToId = null;
+ employee.Subordinates = null;
+
+ employee.TitleOfCourtesy = faker.PickRandom();
+ employee.FirstName = faker.Person.FirstName;
+ employee.LastName = faker.Person.LastName;
+ employee.BirthDate = faker.Date.Past();
+
+ var fakerAddress = faker.Address;
+ employee.Address = new ValueObjects.Address
+ {
+ AddressLine = fakerAddress.StreetAddress(),
+ City = fakerAddress.City(),
+ PostalCode = fakerAddress.ZipCode(),
+ Region = fakerAddress.State(),
+ Country = fakerAddress.Country(),
+ };
+
+ employee.HireDate = faker.Date.Future();
+ employee.Title = faker.PickRandomParam(_jobTitles);
+ employee.Phone = faker.Person.Phone;
+ employee.Extension = faker.Person.Random.Number(0, 999).ToString("000");
+
+ employee.Photo = null;
+
+ //employee.Notes: to be auto-generated by the underlying framework
+ }
+
+}
diff --git a/DomainCore/Eisk.Domains/BaseEntities/Person.cs b/DomainCore/Eisk.Domains/BaseEntities/Person.cs
index 3cb37e88..1a235b75 100644
--- a/DomainCore/Eisk.Domains/BaseEntities/Person.cs
+++ b/DomainCore/Eisk.Domains/BaseEntities/Person.cs
@@ -1,50 +1,49 @@
-using System;
+using Eisk.Domains.Enums;
+using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
-using Eisk.Domains.Enums;
-namespace Eisk.Domains.BaseEntities
-{
- using ValueObjects;
+namespace Eisk.Domains.BaseEntities;
+
+using ValueObjects;
- public class Person
- {
- [Key]
- [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
- public int Id { get; set; }
+public class Person
+{
+ [Key]
+ [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
+ public int Id { get; set; }
- [Display(Name = "Title of Courtesy")]
- [StringLength(10)]
- public TitleOfCourtesy? TitleOfCourtesy { get; set; }
+ [Display(Name = "Title of Courtesy")]
+ [StringLength(10)]
+ public TitleOfCourtesy? TitleOfCourtesy { get; set; }
- [Required(ErrorMessage = "First name required.")]
- [StringLength(15)]
- [Display(Name = "First Name")]
- public string FirstName { get; set; }
+ [Required(ErrorMessage = "First name required.")]
+ [StringLength(50)]
+ [Display(Name = "First Name")]
+ public string FirstName { get; set; }
- [Required(ErrorMessage = "Last name required.")]
- [StringLength(20)]
- [Display(Name = "Last Name")]
- public string LastName { get; set; }
+ [Required(ErrorMessage = "Last name required.")]
+ [StringLength(50)]
+ [Display(Name = "Last Name")]
+ public string LastName { get; set; }
- [Display(Name = "Birth Date")]
- public DateTime? BirthDate { get; set; }
+ [Display(Name = "Birth Date")]
+ public DateTime? BirthDate { get; set; }
- public Address Address { get; set; }
+ public Address Address { get; set; }
- [Required(ErrorMessage = "Phone required")]
- [StringLength(15)]
- public string Phone { get; set; }
+ [Required(ErrorMessage = "Phone required")]
+ [StringLength(50)]
+ public string Phone { get; set; }
- [StringLength(4)]
- public string Extension { get; set; }
+ [StringLength(4)]
+ public string Extension { get; set; }
- [DataType(DataType.MultilineText)]
- [Column(TypeName = "ntext")]
- public string Notes { get; set; }
+ [DataType(DataType.MultilineText)]
+ [Column(TypeName = "ntext")]
+ public string Notes { get; set; }
- [Column(TypeName = "image")]
- public byte[] Photo { get; set; }
+ [Column(TypeName = "image")]
+ public byte[] Photo { get; set; }
- }
-}
\ No newline at end of file
+}
diff --git a/DomainCore/Eisk.Domains/Eisk.Domains.csproj b/DomainCore/Eisk.Domains/Eisk.Domains.csproj
index 5766db61..dbc15171 100644
--- a/DomainCore/Eisk.Domains/Eisk.Domains.csproj
+++ b/DomainCore/Eisk.Domains/Eisk.Domains.csproj
@@ -1,7 +1,7 @@
- netcoreapp2.0
+ net6.0
diff --git a/DomainCore/Eisk.Domains/Entities/Employee.cs b/DomainCore/Eisk.Domains/Entities/Employee.cs
index bf0d7f7c..41cf1779 100644
--- a/DomainCore/Eisk.Domains/Entities/Employee.cs
+++ b/DomainCore/Eisk.Domains/Entities/Employee.cs
@@ -3,26 +3,25 @@
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
-namespace Eisk.Domains.Entities
-{
- using BaseEntities;
+namespace Eisk.Domains.Entities;
+
+using BaseEntities;
- [Table("Employees")]
- public class Employee : Person
- {
- [StringLength(5)]
- public string Title { get; set; }
+[Table("Employees")]
+public class Employee : Person
+{
+ [StringLength(20)]
+ public string Title { get; set; }
- [Display(Name = "Hire Date")]
- public DateTime HireDate { get; set; }
+ [Display(Name = "Hire Date")]
+ public DateTime HireDate { get; set; }
- [Display(Name = "Supervisor")]
- public int? ReportsToId { get; set; }
+ [Display(Name = "Supervisor")]
+ public int? ReportsToId { get; set; }
- [ForeignKey("ReportsToId")]
- public Employee ReportsTo { get; set; }
+ [ForeignKey("ReportsToId")]
+ public Employee ReportsTo { get; set; }
- public virtual IList Subordinates { get; set; }
+ public virtual IList Subordinates { get; set; }
- }
-}
\ No newline at end of file
+}
diff --git a/DomainCore/Eisk.Domains/Enums/TitleOfCourtesy.cs b/DomainCore/Eisk.Domains/Enums/TitleOfCourtesy.cs
index e9bbc535..640bacc6 100644
--- a/DomainCore/Eisk.Domains/Enums/TitleOfCourtesy.cs
+++ b/DomainCore/Eisk.Domains/Enums/TitleOfCourtesy.cs
@@ -1,7 +1,6 @@
-namespace Eisk.Domains.Enums
+namespace Eisk.Domains.Enums;
+
+public enum TitleOfCourtesy
{
- public enum TitleOfCourtesy
- {
- Mr, Dr, Mrs, Ms
- }
-}
\ No newline at end of file
+ Mr, Dr, Mrs, Ms
+}
diff --git a/DomainCore/Eisk.Domains/ValueObjects/Address.cs b/DomainCore/Eisk.Domains/ValueObjects/Address.cs
index f3a282c4..257c7882 100644
--- a/DomainCore/Eisk.Domains/ValueObjects/Address.cs
+++ b/DomainCore/Eisk.Domains/ValueObjects/Address.cs
@@ -1,28 +1,27 @@
using System.ComponentModel.DataAnnotations;
-namespace Eisk.Domains.ValueObjects
+namespace Eisk.Domains.ValueObjects;
+
+public class Address
{
- public class Address
- {
- [StringLength(60)]
- [Required(ErrorMessage = "Address line required.")]
- [Display(Name = "Address line")]
- public string AddressLine { get; set; }
+ [StringLength(80)]
+ [Required(ErrorMessage = "Address line required.")]
+ [Display(Name = "Address line")]
+ public string AddressLine { get; set; }
+
+ [StringLength(80)]
+ public string City { get; set; }
- [StringLength(15)]
- public string City { get; set; }
+ [StringLength(80)]
+ public string Region { get; set; }
- [StringLength(15)]
- public string Region { get; set; }
+ [StringLength(80)]
+ [RegularExpression("\\d{1,80}", ErrorMessage = "Not a valid postal code. Please consider upto 10 digit for valid postal format.")]
+ [Display(Name = "Postal Code")]
+ public string PostalCode { get; set; }
- [StringLength(10)]
- [RegularExpression("\\d{1,10}", ErrorMessage = "Not a valid postal code. Please consider upto 10 digit for valid phone format.")]
- [Display(Name = "Postal Code")]
- public string PostalCode { get; set; }
+ [Required(ErrorMessage = "Country required.")]
+ [StringLength(80)]
+ public string Country { get; set; }
- [Required(ErrorMessage = "Country required.")]
- [StringLength(15)]
- public string Country { get; set; }
-
- }
-}
\ No newline at end of file
+}
diff --git a/Eisk.WebApi.TemplatePack.sln b/Eisk.WebApi.TemplatePack.sln
index 1c103179..45a8032a 100644
--- a/Eisk.WebApi.TemplatePack.sln
+++ b/Eisk.WebApi.TemplatePack.sln
@@ -1,12 +1,16 @@
Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio 15
-VisualStudioVersion = 15.0.26730.8
+# Visual Studio Version 17
+VisualStudioVersion = 17.0.32112.339
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Eisk.Core", "Core\Eisk.Core\Eisk.Core.csproj", "{8E6823DD-60AB-4772-AB9C-E5786BEF2B50}"
EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{4E93D3D8-EC59-4DE2-A1E1-3F0258277780}"
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Build", "Build", "{4E93D3D8-EC59-4DE2-A1E1-3F0258277780}"
ProjectSection(SolutionItems) = preProject
+ build\dnn-install-from-local.cmd = build\dnn-install-from-local.cmd
+ build\dnn-install-from-remote.cmd = build\dnn-install-from-remote.cmd
+ build\git-bash-echo.sh = build\git-bash-echo.sh
+ build\git-push.sh = build\git-push.sh
.template.config\template.json = .template.config\template.json
.template.config\template.vstemplate = .template.config\template.vstemplate
EndProjectSection
@@ -21,8 +25,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Core", "Core", "{CEBF47DF-D
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Test.Core", "Test.Core", "{16043213-DF69-4E37-98E1-2C86C410551B}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Eisk.WebApi", "WebApi\Eisk.WebApi\Eisk.WebApi.csproj", "{99D535CA-1DE1-459B-8ECC-B4F6936F5142}"
-EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "WebApi", "WebApi", "{9611B3D6-810A-4E98-9166-2DA770E38B81}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Infrastructure", "Infrastructure", "{8D09A735-BB55-4075-9B06-EAAA18F59781}"
@@ -43,11 +45,33 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Eisk.DataServices.EFCore",
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Eisk.EFCore.Setup", "Infrastructure.EFCore\Eisk.EFCore.Setup\Eisk.EFCore.Setup.csproj", "{5C60F4F8-B7A7-4B14-B476-79E138BAF1F9}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Eisk.DataServices.EFCore.IntegrationTests", "Infrastructure.EFCore\Eisk.DataServices.EFCore.IntegrationTests\Eisk.DataServices.EFCore.IntegrationTests.csproj", "{57348807-E087-4B0F-906E-72E4768B693C}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Eisk.DomainServices.ComponentTests.EFCore", "Infrastructure.EFCore\Eisk.DomainServices.ComponentTests.EFCore\Eisk.DomainServices.ComponentTests.EFCore.csproj", "{CB7B38B4-9AE5-4B86-BC31-CD74F8690D79}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Eisk.DataServices.EFCore.IntegrationTests.Ext", "Infrastructure.EFCore\Eisk.DataServices.EFCore.IntegrationTests.Ext\Eisk.DataServices.EFCore.IntegrationTests.Ext.csproj", "{BB413B48-E598-47C8-AF1B-887203391F8E}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Eisk.WebApi", "WebApi\Eisk.WebApi\Eisk.WebApi.csproj", "{B99A94EA-9D76-4C67-88E2-A1814930E8B5}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Eisk.DomainServices.ComponentTests.EFCore", "Infrastructure.EFCore\Eisk.DomainServices.ComponentTests.EFCore\Eisk.DomainServices.ComponentTests.EFCore.csproj", "{CB7B38B4-9AE5-4B86-BC31-CD74F8690D79}"
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Notes", "Notes", "{ACEB7D4D-4789-49F0-A552-3D7C0A419FB9}"
+ ProjectSection(SolutionItems) = preProject
+ Notes\Business-Rules.txt = Notes\Business-Rules.txt
+ Notes\Dev-Set-up.txt = Notes\Dev-Set-up.txt
+ Notes\Eisk-Features.txt = Notes\Eisk-Features.txt
+ Notes\Entity-Samples.txt = Notes\Entity-Samples.txt
+ Notes\Modules.txt = Notes\Modules.txt
+ Notes\Release-Instructions.txt = Notes\Release-Instructions.txt
+ Notes\Test-Strategy.txt = Notes\Test-Strategy.txt
+ Notes\TODO.txt = Notes\TODO.txt
+ Notes\Troubleshoot.txt = Notes\Troubleshoot.txt
+ EndProjectSection
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Eisk.Domains.TestData", "DomainCore\Eisk.Domains.TestData\Eisk.Domains.TestData.csproj", "{D0227185-3F9D-41B4-9314-C7B3CBC38D6F}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Eisk.DataServices.IntegrationTests.EFCore.InMemory", "Infrastructure.EFCore\Eisk.DataServices.IntegrationTests.EFCore.InMemory\Eisk.DataServices.IntegrationTests.EFCore.InMemory.csproj", "{6FDA83B9-3E99-47AB-B232-E161C817BD1D}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Eisk.DataServices.IntegrationTests.EFCore.SqlServer", "Infrastructure.EFCore\Eisk.DataServices.IntegrationTests.EFCore.SqlServer\Eisk.DataServices.IntegrationTests.EFCore.SqlServer.csproj", "{1502582C-70E8-492E-8366-D85699C405E2}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Docs", "Docs", "{D6C07FAD-F2A3-4C45-83C4-219E4EC79384}"
+ ProjectSection(SolutionItems) = preProject
+ README.md = README.md
+ EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -71,10 +95,6 @@ Global
{DCDCAE0A-4CF7-44CA-96A1-BDD70087D575}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DCDCAE0A-4CF7-44CA-96A1-BDD70087D575}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DCDCAE0A-4CF7-44CA-96A1-BDD70087D575}.Release|Any CPU.Build.0 = Release|Any CPU
- {99D535CA-1DE1-459B-8ECC-B4F6936F5142}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {99D535CA-1DE1-459B-8ECC-B4F6936F5142}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {99D535CA-1DE1-459B-8ECC-B4F6936F5142}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {99D535CA-1DE1-459B-8ECC-B4F6936F5142}.Release|Any CPU.Build.0 = Release|Any CPU
{8824BF10-E351-4F9E-B462-B86F51CA234E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8824BF10-E351-4F9E-B462-B86F51CA234E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8824BF10-E351-4F9E-B462-B86F51CA234E}.Release|Any CPU.ActiveCfg = Release|Any CPU
@@ -103,18 +123,26 @@ Global
{5C60F4F8-B7A7-4B14-B476-79E138BAF1F9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5C60F4F8-B7A7-4B14-B476-79E138BAF1F9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5C60F4F8-B7A7-4B14-B476-79E138BAF1F9}.Release|Any CPU.Build.0 = Release|Any CPU
- {57348807-E087-4B0F-906E-72E4768B693C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {57348807-E087-4B0F-906E-72E4768B693C}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {57348807-E087-4B0F-906E-72E4768B693C}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {57348807-E087-4B0F-906E-72E4768B693C}.Release|Any CPU.Build.0 = Release|Any CPU
- {BB413B48-E598-47C8-AF1B-887203391F8E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {BB413B48-E598-47C8-AF1B-887203391F8E}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {BB413B48-E598-47C8-AF1B-887203391F8E}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {BB413B48-E598-47C8-AF1B-887203391F8E}.Release|Any CPU.Build.0 = Release|Any CPU
{CB7B38B4-9AE5-4B86-BC31-CD74F8690D79}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{CB7B38B4-9AE5-4B86-BC31-CD74F8690D79}.Debug|Any CPU.Build.0 = Debug|Any CPU
{CB7B38B4-9AE5-4B86-BC31-CD74F8690D79}.Release|Any CPU.ActiveCfg = Release|Any CPU
{CB7B38B4-9AE5-4B86-BC31-CD74F8690D79}.Release|Any CPU.Build.0 = Release|Any CPU
+ {B99A94EA-9D76-4C67-88E2-A1814930E8B5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {B99A94EA-9D76-4C67-88E2-A1814930E8B5}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B99A94EA-9D76-4C67-88E2-A1814930E8B5}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {B99A94EA-9D76-4C67-88E2-A1814930E8B5}.Release|Any CPU.Build.0 = Release|Any CPU
+ {D0227185-3F9D-41B4-9314-C7B3CBC38D6F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {D0227185-3F9D-41B4-9314-C7B3CBC38D6F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {D0227185-3F9D-41B4-9314-C7B3CBC38D6F}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {D0227185-3F9D-41B4-9314-C7B3CBC38D6F}.Release|Any CPU.Build.0 = Release|Any CPU
+ {6FDA83B9-3E99-47AB-B232-E161C817BD1D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {6FDA83B9-3E99-47AB-B232-E161C817BD1D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {6FDA83B9-3E99-47AB-B232-E161C817BD1D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {6FDA83B9-3E99-47AB-B232-E161C817BD1D}.Release|Any CPU.Build.0 = Release|Any CPU
+ {1502582C-70E8-492E-8366-D85699C405E2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {1502582C-70E8-492E-8366-D85699C405E2}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {1502582C-70E8-492E-8366-D85699C405E2}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {1502582C-70E8-492E-8366-D85699C405E2}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -125,16 +153,17 @@ Global
{1BC9EBFE-A17A-43FB-AB9D-C429CCD8020D} = {CEBF47DF-D79A-4AE0-A857-A51D438E3C39}
{DCDCAE0A-4CF7-44CA-96A1-BDD70087D575} = {16043213-DF69-4E37-98E1-2C86C410551B}
{16043213-DF69-4E37-98E1-2C86C410551B} = {CEBF47DF-D79A-4AE0-A857-A51D438E3C39}
- {99D535CA-1DE1-459B-8ECC-B4F6936F5142} = {9611B3D6-810A-4E98-9166-2DA770E38B81}
{EC2CC663-1674-4F39-B3A5-926F3A83094A} = {07B09CE7-77B7-4F0F-9BF1-1CA13B8501D8}
{ABA6FD15-BB90-478E-91F1-7A8E5708DCDF} = {07B09CE7-77B7-4F0F-9BF1-1CA13B8501D8}
{19C8978D-7873-4306-B498-6D29C2F0013E} = {07B09CE7-77B7-4F0F-9BF1-1CA13B8501D8}
{77414DF8-79D7-4879-AEA6-EAA237639F67} = {07B09CE7-77B7-4F0F-9BF1-1CA13B8501D8}
{521DC48B-EE63-41DB-B226-382EE39A3CF8} = {8D09A735-BB55-4075-9B06-EAAA18F59781}
{5C60F4F8-B7A7-4B14-B476-79E138BAF1F9} = {8D09A735-BB55-4075-9B06-EAAA18F59781}
- {57348807-E087-4B0F-906E-72E4768B693C} = {8D09A735-BB55-4075-9B06-EAAA18F59781}
- {BB413B48-E598-47C8-AF1B-887203391F8E} = {8D09A735-BB55-4075-9B06-EAAA18F59781}
{CB7B38B4-9AE5-4B86-BC31-CD74F8690D79} = {8D09A735-BB55-4075-9B06-EAAA18F59781}
+ {B99A94EA-9D76-4C67-88E2-A1814930E8B5} = {9611B3D6-810A-4E98-9166-2DA770E38B81}
+ {D0227185-3F9D-41B4-9314-C7B3CBC38D6F} = {07B09CE7-77B7-4F0F-9BF1-1CA13B8501D8}
+ {6FDA83B9-3E99-47AB-B232-E161C817BD1D} = {8D09A735-BB55-4075-9B06-EAAA18F59781}
+ {1502582C-70E8-492E-8366-D85699C405E2} = {8D09A735-BB55-4075-9B06-EAAA18F59781}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {4370F72B-9D16-4EBF-8EF5-1F0925FC7CC6}
diff --git a/Eisk.WebApi.TemplatePack/Eisk.WebApi.TemplatePack.csproj b/Eisk.WebApi.TemplatePack/Eisk.WebApi.TemplatePack.csproj
index 0a6f3df9..f541917d 100644
--- a/Eisk.WebApi.TemplatePack/Eisk.WebApi.TemplatePack.csproj
+++ b/Eisk.WebApi.TemplatePack/Eisk.WebApi.TemplatePack.csproj
@@ -7,6 +7,7 @@
Program
$(DevEnvDir)\devenv.exe
/rootsuffix Exp
+
@@ -20,7 +21,7 @@
Properties
Eisk.WebApi
Eisk.WebApi
- v4.6
+ v4.8
false
false
false
@@ -62,6 +63,7 @@
+
true
diff --git a/Eisk.WebApi.TemplatePack/README.txt b/Eisk.WebApi.TemplatePack/README.txt
new file mode 100644
index 00000000..a2a40dff
--- /dev/null
+++ b/Eisk.WebApi.TemplatePack/README.txt
@@ -0,0 +1,13 @@
+=========================================
+Build, Publish and Test Nuget Package (dotnet)
+
+=========================================
+Build, Publish and Test VSIX
+
+=========================================
+Build, Publish and Test Github Release
+
+=========================================
+Build, Publish and Test Github Release
+
+=========================================
\ No newline at end of file
diff --git a/Eisk.WebApi.TemplatePack/source.extension.vsixmanifest b/Eisk.WebApi.TemplatePack/source.extension.vsixmanifest
index 3032b169..590ea622 100644
--- a/Eisk.WebApi.TemplatePack/source.extension.vsixmanifest
+++ b/Eisk.WebApi.TemplatePack/source.extension.vsixmanifest
@@ -1,7 +1,7 @@
-
+
Eisk.WebApi
Project template with simple CRUD to get started ASP.NET Web Api quickly.
diff --git a/Eisk.WebApi.TemplatePack/template/Eisk.WebApi.proj b/Eisk.WebApi.TemplatePack/template/Eisk.WebApi.proj
index b751ffbf..8d8522b3 100644
--- a/Eisk.WebApi.TemplatePack/template/Eisk.WebApi.proj
+++ b/Eisk.WebApi.TemplatePack/template/Eisk.WebApi.proj
@@ -9,7 +9,7 @@
Ashraf Alam
Project template with simple CRUD to get started ASP.NET Web Api quickly.
- 1.0.6
+ 9.0.10
@@ -26,6 +26,10 @@
+
+
+
+
diff --git a/Eisk.WebApi.sln b/Eisk.WebApi.sln
index 056bc68f..6acee948 100644
--- a/Eisk.WebApi.sln
+++ b/Eisk.WebApi.sln
@@ -1,31 +1,37 @@
Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio 15
-VisualStudioVersion = 15.0.28307.168
+# Visual Studio Version 17
+VisualStudioVersion = 17.0.32112.339
MinimumVisualStudioVersion = 10.0.40219.1
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Core", "Core", "{5C899B87-C8F5-4175-8D58-8EBBD0DAF2D6}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Eisk.Core", "Core\Eisk.Core\Eisk.Core.csproj", "{8E6823DD-60AB-4772-AB9C-E5786BEF2B50}"
EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "DomainCore", "DomainCore", "{EBB00523-AA34-473E-869F-F21A1FF49E4A}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Eisk.Test.Core", "Core\Eisk.Test.Core\Eisk.Test.Core.csproj", "{642F6C34-DFFF-47FB-8568-621423F95B79}"
EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Infrastructure", "Infrastructure", "{AB873FBC-C5FF-4186-9C40-1B07B5869061}"
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Core", "Core", "{CEBF47DF-D79A-4AE0-A857-A51D438E3C39}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Eisk.Core", "Core\Eisk.Core\Eisk.Core.csproj", "{DD9E265E-D7AF-4CBD-8316-707608C35920}"
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Test.Core", "Test.Core", "{16043213-DF69-4E37-98E1-2C86C410551B}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Eisk.Test.Core", "Core\Eisk.Test.Core\Eisk.Test.Core.csproj", "{32A37BEF-1EEB-4937-B7B1-43DC7C8CFB08}"
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "WebApi", "WebApi", "{9611B3D6-810A-4E98-9166-2DA770E38B81}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Eisk.Domains", "DomainCore\Eisk.Domains\Eisk.Domains.csproj", "{32AA2C19-860E-4B59-9A14-59E5886433D4}"
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Infrastructure", "Infrastructure", "{8D09A735-BB55-4075-9B06-EAAA18F59781}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Eisk.DataServices.Interfaces", "DomainCore\Eisk.DataServices.Interfaces\Eisk.DataServices.Interfaces.csproj", "{8493028D-21C0-43BC-A382-3390A58133B2}"
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "DomainCore", "DomainCore", "{07B09CE7-77B7-4F0F-9BF1-1CA13B8501D8}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Eisk.WebApi", "WebApi\Eisk.WebApi\Eisk.WebApi.csproj", "{3EB34FF1-B49A-4B99-9147-47A858F18E9E}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Eisk.Domains", "DomainCore\Eisk.Domains\Eisk.Domains.csproj", "{EC2CC663-1674-4F39-B3A5-926F3A83094A}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Eisk.EFCore.Setup", "Infrastructure.EFCore\Eisk.EFCore.Setup\Eisk.EFCore.Setup.csproj", "{64004E6C-5178-42AD-B685-7377F4D30F73}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Eisk.DataServices.Interfaces", "DomainCore\Eisk.DataServices.Interfaces\Eisk.DataServices.Interfaces.csproj", "{ABA6FD15-BB90-478E-91F1-7A8E5708DCDF}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Eisk.DomainServices", "DomainCore\Eisk.DomainServices\Eisk.DomainServices.csproj", "{51C04044-27E4-422E-9B5F-AB3AD047D07E}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Eisk.DomainServices", "DomainCore\Eisk.DomainServices\Eisk.DomainServices.csproj", "{19C8978D-7873-4306-B498-6D29C2F0013E}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Eisk.DataServices.EFCore", "Infrastructure.EFCore\Eisk.DataServices.EFCore\Eisk.DataServices.EFCore.csproj", "{5439FE0B-7094-41AE-AFC2-FAA340E5EAE4}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Eisk.DataServices.EFCore", "Infrastructure.EFCore\Eisk.DataServices.EFCore\Eisk.DataServices.EFCore.csproj", "{521DC48B-EE63-41DB-B226-382EE39A3CF8}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Eisk.DomainServices.ComponentTests.EFCore", "Infrastructure.EFCore\Eisk.DomainServices.ComponentTests.EFCore\Eisk.DomainServices.ComponentTests.EFCore.csproj", "{927DF350-D0DA-410B-86F1-10A6EE30D15C}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Eisk.EFCore.Setup", "Infrastructure.EFCore\Eisk.EFCore.Setup\Eisk.EFCore.Setup.csproj", "{5C60F4F8-B7A7-4B14-B476-79E138BAF1F9}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Eisk.DomainServices.ComponentTests.EFCore", "Infrastructure.EFCore\Eisk.DomainServices.ComponentTests.EFCore\Eisk.DomainServices.ComponentTests.EFCore.csproj", "{CB7B38B4-9AE5-4B86-BC31-CD74F8690D79}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Eisk.WebApi", "WebApi\Eisk.WebApi\Eisk.WebApi.csproj", "{B99A94EA-9D76-4C67-88E2-A1814930E8B5}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Eisk.Domains.TestData", "DomainCore\Eisk.Domains.TestData\Eisk.Domains.TestData.csproj", "{E2893FF6-17A0-4C27-9109-12705F62815E}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -33,57 +39,64 @@ Global
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {DD9E265E-D7AF-4CBD-8316-707608C35920}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {DD9E265E-D7AF-4CBD-8316-707608C35920}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {DD9E265E-D7AF-4CBD-8316-707608C35920}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {DD9E265E-D7AF-4CBD-8316-707608C35920}.Release|Any CPU.Build.0 = Release|Any CPU
- {32A37BEF-1EEB-4937-B7B1-43DC7C8CFB08}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {32A37BEF-1EEB-4937-B7B1-43DC7C8CFB08}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {32A37BEF-1EEB-4937-B7B1-43DC7C8CFB08}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {32A37BEF-1EEB-4937-B7B1-43DC7C8CFB08}.Release|Any CPU.Build.0 = Release|Any CPU
- {32AA2C19-860E-4B59-9A14-59E5886433D4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {32AA2C19-860E-4B59-9A14-59E5886433D4}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {32AA2C19-860E-4B59-9A14-59E5886433D4}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {32AA2C19-860E-4B59-9A14-59E5886433D4}.Release|Any CPU.Build.0 = Release|Any CPU
- {8493028D-21C0-43BC-A382-3390A58133B2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {8493028D-21C0-43BC-A382-3390A58133B2}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {8493028D-21C0-43BC-A382-3390A58133B2}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {8493028D-21C0-43BC-A382-3390A58133B2}.Release|Any CPU.Build.0 = Release|Any CPU
- {3EB34FF1-B49A-4B99-9147-47A858F18E9E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {3EB34FF1-B49A-4B99-9147-47A858F18E9E}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {3EB34FF1-B49A-4B99-9147-47A858F18E9E}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {3EB34FF1-B49A-4B99-9147-47A858F18E9E}.Release|Any CPU.Build.0 = Release|Any CPU
- {64004E6C-5178-42AD-B685-7377F4D30F73}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {64004E6C-5178-42AD-B685-7377F4D30F73}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {64004E6C-5178-42AD-B685-7377F4D30F73}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {64004E6C-5178-42AD-B685-7377F4D30F73}.Release|Any CPU.Build.0 = Release|Any CPU
- {51C04044-27E4-422E-9B5F-AB3AD047D07E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {51C04044-27E4-422E-9B5F-AB3AD047D07E}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {51C04044-27E4-422E-9B5F-AB3AD047D07E}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {51C04044-27E4-422E-9B5F-AB3AD047D07E}.Release|Any CPU.Build.0 = Release|Any CPU
- {5439FE0B-7094-41AE-AFC2-FAA340E5EAE4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {5439FE0B-7094-41AE-AFC2-FAA340E5EAE4}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {5439FE0B-7094-41AE-AFC2-FAA340E5EAE4}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {5439FE0B-7094-41AE-AFC2-FAA340E5EAE4}.Release|Any CPU.Build.0 = Release|Any CPU
- {927DF350-D0DA-410B-86F1-10A6EE30D15C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {927DF350-D0DA-410B-86F1-10A6EE30D15C}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {927DF350-D0DA-410B-86F1-10A6EE30D15C}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {927DF350-D0DA-410B-86F1-10A6EE30D15C}.Release|Any CPU.Build.0 = Release|Any CPU
+ {8E6823DD-60AB-4772-AB9C-E5786BEF2B50}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {8E6823DD-60AB-4772-AB9C-E5786BEF2B50}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {8E6823DD-60AB-4772-AB9C-E5786BEF2B50}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {8E6823DD-60AB-4772-AB9C-E5786BEF2B50}.Release|Any CPU.Build.0 = Release|Any CPU
+ {642F6C34-DFFF-47FB-8568-621423F95B79}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {642F6C34-DFFF-47FB-8568-621423F95B79}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {642F6C34-DFFF-47FB-8568-621423F95B79}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {642F6C34-DFFF-47FB-8568-621423F95B79}.Release|Any CPU.Build.0 = Release|Any CPU
+ {EC2CC663-1674-4F39-B3A5-926F3A83094A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {EC2CC663-1674-4F39-B3A5-926F3A83094A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {EC2CC663-1674-4F39-B3A5-926F3A83094A}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {EC2CC663-1674-4F39-B3A5-926F3A83094A}.Release|Any CPU.Build.0 = Release|Any CPU
+ {ABA6FD15-BB90-478E-91F1-7A8E5708DCDF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {ABA6FD15-BB90-478E-91F1-7A8E5708DCDF}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {ABA6FD15-BB90-478E-91F1-7A8E5708DCDF}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {ABA6FD15-BB90-478E-91F1-7A8E5708DCDF}.Release|Any CPU.Build.0 = Release|Any CPU
+ {19C8978D-7873-4306-B498-6D29C2F0013E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {19C8978D-7873-4306-B498-6D29C2F0013E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {19C8978D-7873-4306-B498-6D29C2F0013E}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {19C8978D-7873-4306-B498-6D29C2F0013E}.Release|Any CPU.Build.0 = Release|Any CPU
+ {521DC48B-EE63-41DB-B226-382EE39A3CF8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {521DC48B-EE63-41DB-B226-382EE39A3CF8}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {521DC48B-EE63-41DB-B226-382EE39A3CF8}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {521DC48B-EE63-41DB-B226-382EE39A3CF8}.Release|Any CPU.Build.0 = Release|Any CPU
+ {5C60F4F8-B7A7-4B14-B476-79E138BAF1F9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {5C60F4F8-B7A7-4B14-B476-79E138BAF1F9}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {5C60F4F8-B7A7-4B14-B476-79E138BAF1F9}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {5C60F4F8-B7A7-4B14-B476-79E138BAF1F9}.Release|Any CPU.Build.0 = Release|Any CPU
+ {CB7B38B4-9AE5-4B86-BC31-CD74F8690D79}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {CB7B38B4-9AE5-4B86-BC31-CD74F8690D79}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {CB7B38B4-9AE5-4B86-BC31-CD74F8690D79}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {CB7B38B4-9AE5-4B86-BC31-CD74F8690D79}.Release|Any CPU.Build.0 = Release|Any CPU
+ {B99A94EA-9D76-4C67-88E2-A1814930E8B5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {B99A94EA-9D76-4C67-88E2-A1814930E8B5}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B99A94EA-9D76-4C67-88E2-A1814930E8B5}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {B99A94EA-9D76-4C67-88E2-A1814930E8B5}.Release|Any CPU.Build.0 = Release|Any CPU
+ {E2893FF6-17A0-4C27-9109-12705F62815E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {E2893FF6-17A0-4C27-9109-12705F62815E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {E2893FF6-17A0-4C27-9109-12705F62815E}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {E2893FF6-17A0-4C27-9109-12705F62815E}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
- {DD9E265E-D7AF-4CBD-8316-707608C35920} = {5C899B87-C8F5-4175-8D58-8EBBD0DAF2D6}
- {32A37BEF-1EEB-4937-B7B1-43DC7C8CFB08} = {5C899B87-C8F5-4175-8D58-8EBBD0DAF2D6}
- {32AA2C19-860E-4B59-9A14-59E5886433D4} = {EBB00523-AA34-473E-869F-F21A1FF49E4A}
- {8493028D-21C0-43BC-A382-3390A58133B2} = {EBB00523-AA34-473E-869F-F21A1FF49E4A}
- {64004E6C-5178-42AD-B685-7377F4D30F73} = {AB873FBC-C5FF-4186-9C40-1B07B5869061}
- {51C04044-27E4-422E-9B5F-AB3AD047D07E} = {EBB00523-AA34-473E-869F-F21A1FF49E4A}
- {5439FE0B-7094-41AE-AFC2-FAA340E5EAE4} = {AB873FBC-C5FF-4186-9C40-1B07B5869061}
- {927DF350-D0DA-410B-86F1-10A6EE30D15C} = {AB873FBC-C5FF-4186-9C40-1B07B5869061}
+ {8E6823DD-60AB-4772-AB9C-E5786BEF2B50} = {CEBF47DF-D79A-4AE0-A857-A51D438E3C39}
+ {642F6C34-DFFF-47FB-8568-621423F95B79} = {16043213-DF69-4E37-98E1-2C86C410551B}
+ {16043213-DF69-4E37-98E1-2C86C410551B} = {CEBF47DF-D79A-4AE0-A857-A51D438E3C39}
+ {EC2CC663-1674-4F39-B3A5-926F3A83094A} = {07B09CE7-77B7-4F0F-9BF1-1CA13B8501D8}
+ {ABA6FD15-BB90-478E-91F1-7A8E5708DCDF} = {07B09CE7-77B7-4F0F-9BF1-1CA13B8501D8}
+ {19C8978D-7873-4306-B498-6D29C2F0013E} = {07B09CE7-77B7-4F0F-9BF1-1CA13B8501D8}
+ {521DC48B-EE63-41DB-B226-382EE39A3CF8} = {8D09A735-BB55-4075-9B06-EAAA18F59781}
+ {5C60F4F8-B7A7-4B14-B476-79E138BAF1F9} = {8D09A735-BB55-4075-9B06-EAAA18F59781}
+ {CB7B38B4-9AE5-4B86-BC31-CD74F8690D79} = {8D09A735-BB55-4075-9B06-EAAA18F59781}
+ {B99A94EA-9D76-4C67-88E2-A1814930E8B5} = {9611B3D6-810A-4E98-9166-2DA770E38B81}
+ {E2893FF6-17A0-4C27-9109-12705F62815E} = {07B09CE7-77B7-4F0F-9BF1-1CA13B8501D8}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
- SolutionGuid = {32A159D0-95EE-45EA-AB3A-ABC2DAF5FF5D}
+ SolutionGuid = {4370F72B-9D16-4EBF-8EF5-1F0925FC7CC6}
EndGlobalSection
EndGlobal
diff --git a/Infrastructure.EFCore/Eisk.DataServices.EFCore.IntegrationTests.Ext/EmployeeDataServiceBaseIntegrationTests.cs b/Infrastructure.EFCore/Eisk.DataServices.EFCore.IntegrationTests.Ext/EmployeeDataServiceBaseIntegrationTests.cs
deleted file mode 100644
index 3397f32f..00000000
--- a/Infrastructure.EFCore/Eisk.DataServices.EFCore.IntegrationTests.Ext/EmployeeDataServiceBaseIntegrationTests.cs
+++ /dev/null
@@ -1,15 +0,0 @@
-using Eisk.DataServices.Interfaces;
-using Eisk.Domains.Entities;
-using Eisk.Test.Core.TestBases;
-
-namespace Eisk.DataServices.EFCore.IntegrationTests.Ext
-{
- public abstract class EmployeeDataServiceBaseIntegrationTests : DataServiceBaseIntegrationTests
- {
- protected EmployeeDataServiceBaseIntegrationTests(IEmployeeDataService employeeDataService) :base (employeeDataService, x => x.Id)
- {
-
- }
-
- }
-}
diff --git a/Infrastructure.EFCore/Eisk.DataServices.EFCore.IntegrationTests.Ext/EmployeeDataServiceTests.cs b/Infrastructure.EFCore/Eisk.DataServices.EFCore.IntegrationTests.Ext/EmployeeDataServiceTests.cs
deleted file mode 100644
index aff1f2d5..00000000
--- a/Infrastructure.EFCore/Eisk.DataServices.EFCore.IntegrationTests.Ext/EmployeeDataServiceTests.cs
+++ /dev/null
@@ -1,13 +0,0 @@
-namespace Eisk.DataServices.EFCore.IntegrationTests.Ext
-{
- using Eisk.EFCore.Setup;
-
- public class EmployeeDataServiceTests: EmployeeDataServiceBaseIntegrationTests
- {
- public EmployeeDataServiceTests():base (new EmployeeDataService(TestDbContextFactory.CreateDbContext()))
- {
-
- }
-
- }
-}
diff --git a/Infrastructure.EFCore/Eisk.DataServices.EFCore.IntegrationTests/EmployeeDataServiceTests.cs b/Infrastructure.EFCore/Eisk.DataServices.EFCore.IntegrationTests/EmployeeDataServiceTests.cs
deleted file mode 100644
index 37c2a9d3..00000000
--- a/Infrastructure.EFCore/Eisk.DataServices.EFCore.IntegrationTests/EmployeeDataServiceTests.cs
+++ /dev/null
@@ -1,16 +0,0 @@
-
-namespace Eisk.DataServices.EFCore.IntegrationTests
-{
- using Eisk.EFCore.Setup;
- using Domains.Entities;
- using Test.Core.TestBases;
-
- public class EmployeeDataServiceTests: DataServiceBaseIntegrationTests
- {
- public EmployeeDataServiceTests():base (new EmployeeDataService(TestDbContextFactory.CreateDbContext()), x => x.Id)
- {
-
- }
-
- }
-}
diff --git a/Infrastructure.EFCore/Eisk.DataServices.EFCore/Eisk.DataServices.EFCore.csproj b/Infrastructure.EFCore/Eisk.DataServices.EFCore/Eisk.DataServices.EFCore.csproj
index 9cdb13f3..aa90495d 100644
--- a/Infrastructure.EFCore/Eisk.DataServices.EFCore/Eisk.DataServices.EFCore.csproj
+++ b/Infrastructure.EFCore/Eisk.DataServices.EFCore/Eisk.DataServices.EFCore.csproj
@@ -1,7 +1,7 @@
- netcoreapp2.0
+ net6.0
diff --git a/Infrastructure.EFCore/Eisk.DataServices.EFCore/EmployeeDataService.cs b/Infrastructure.EFCore/Eisk.DataServices.EFCore/EmployeeDataService.cs
index b830f0de..976dfb8a 100644
--- a/Infrastructure.EFCore/Eisk.DataServices.EFCore/EmployeeDataService.cs
+++ b/Infrastructure.EFCore/Eisk.DataServices.EFCore/EmployeeDataService.cs
@@ -1,26 +1,25 @@
+using Eisk.Core.DataService.EFCore;
+using Microsoft.EntityFrameworkCore;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
-using Eisk.Core.DataService.EFCore;
-using Microsoft.EntityFrameworkCore;
-namespace Eisk.DataServices.EFCore
-{
- using DataContext;
- using Interfaces;
- using Domains.Entities;
+namespace Eisk.DataServices.EFCore;
- public class EmployeeDataService : EntityDataService, IEmployeeDataService
- {
- public EmployeeDataService(AppDbContext dbContext) : base(dbContext)
- {
+using DataContext;
+using Domains.Entities;
+using Interfaces;
- }
+public class EmployeeDataService : EntityDataService, IEmployeeDataService
+{
+ public EmployeeDataService(AppDbContext dbContext) : base(dbContext)
+ {
- public virtual async Task> GetByFirstName(string firstName)
- {
- return await DbContext.Set().Where(x => x.FirstName.Contains(firstName)).ToListAsync();
- }
+ }
+ public virtual async Task> GetByFirstName(string firstName)
+ {
+ return await DbContext.Set().Where(x => x.FirstName.Contains(firstName)).ToListAsync();
}
-}
\ No newline at end of file
+
+}
diff --git a/Infrastructure.EFCore/Eisk.DataServices.EFCore.IntegrationTests/Eisk.DataServices.EFCore.IntegrationTests.csproj b/Infrastructure.EFCore/Eisk.DataServices.IntegrationTests.EFCore.InMemory/Eisk.DataServices.IntegrationTests.EFCore.InMemory.csproj
similarity index 65%
rename from Infrastructure.EFCore/Eisk.DataServices.EFCore.IntegrationTests/Eisk.DataServices.EFCore.IntegrationTests.csproj
rename to Infrastructure.EFCore/Eisk.DataServices.IntegrationTests.EFCore.InMemory/Eisk.DataServices.IntegrationTests.EFCore.InMemory.csproj
index f96ba703..d7c63470 100644
--- a/Infrastructure.EFCore/Eisk.DataServices.EFCore.IntegrationTests/Eisk.DataServices.EFCore.IntegrationTests.csproj
+++ b/Infrastructure.EFCore/Eisk.DataServices.IntegrationTests.EFCore.InMemory/Eisk.DataServices.IntegrationTests.EFCore.InMemory.csproj
@@ -1,15 +1,18 @@
- netcoreapp2.0
+ net6.0
false
-
-
-
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
diff --git a/Infrastructure.EFCore/Eisk.DataServices.IntegrationTests.EFCore.InMemory/EmployeeDataServiceTestsWithInMemoryDb.cs b/Infrastructure.EFCore/Eisk.DataServices.IntegrationTests.EFCore.InMemory/EmployeeDataServiceTestsWithInMemoryDb.cs
new file mode 100644
index 00000000..97a716c2
--- /dev/null
+++ b/Infrastructure.EFCore/Eisk.DataServices.IntegrationTests.EFCore.InMemory/EmployeeDataServiceTestsWithInMemoryDb.cs
@@ -0,0 +1,15 @@
+namespace Eisk.DataServices.IntegrationTests.EFCore.InMemory;
+
+using Domains.Entities;
+using Eisk.DataServices.EFCore;
+using Eisk.EFCore.Setup;
+using Test.Core.TestBases;
+
+public class EmployeeDataServiceTestsWithInMemoryDb : DataServiceBaseIntegrationTests
+{
+ public EmployeeDataServiceTestsWithInMemoryDb() : base(new EmployeeDataService(TestDbContextFactory.CreateInMemoryDbContext()), x => x.Id)
+ {
+
+ }
+
+}
diff --git a/Infrastructure.EFCore/Eisk.DataServices.IntegrationTests.EFCore.SqlServer/DatabaseSetup.cs b/Infrastructure.EFCore/Eisk.DataServices.IntegrationTests.EFCore.SqlServer/DatabaseSetup.cs
new file mode 100644
index 00000000..bc1f0be6
--- /dev/null
+++ b/Infrastructure.EFCore/Eisk.DataServices.IntegrationTests.EFCore.SqlServer/DatabaseSetup.cs
@@ -0,0 +1,19 @@
+using Eisk.EFCore.Setup;
+using System;
+
+namespace Eisk.DataServices.IntegrationTests.EFCore.SqlServer;
+
+public class DatabaseSetup : IDisposable
+{
+ public DatabaseSetup()
+ {
+ var db = TestDbContextFactory.CreateSqlServerDbContext();
+ DbContextDataInitializer.Initialize(db);
+ }
+
+ public void Dispose()
+ {
+ // ... clean up test data from the database ...
+ }
+
+}
diff --git a/Infrastructure.EFCore/Eisk.DataServices.EFCore.IntegrationTests.Ext/Eisk.DataServices.EFCore.IntegrationTests.Ext.csproj b/Infrastructure.EFCore/Eisk.DataServices.IntegrationTests.EFCore.SqlServer/Eisk.DataServices.IntegrationTests.EFCore.SqlServer.csproj
similarity index 65%
rename from Infrastructure.EFCore/Eisk.DataServices.EFCore.IntegrationTests.Ext/Eisk.DataServices.EFCore.IntegrationTests.Ext.csproj
rename to Infrastructure.EFCore/Eisk.DataServices.IntegrationTests.EFCore.SqlServer/Eisk.DataServices.IntegrationTests.EFCore.SqlServer.csproj
index f96ba703..d7c63470 100644
--- a/Infrastructure.EFCore/Eisk.DataServices.EFCore.IntegrationTests.Ext/Eisk.DataServices.EFCore.IntegrationTests.Ext.csproj
+++ b/Infrastructure.EFCore/Eisk.DataServices.IntegrationTests.EFCore.SqlServer/Eisk.DataServices.IntegrationTests.EFCore.SqlServer.csproj
@@ -1,15 +1,18 @@
- netcoreapp2.0
+ net6.0
false
-
-
-
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
diff --git a/Infrastructure.EFCore/Eisk.DataServices.IntegrationTests.EFCore.SqlServer/EmployeeDataServiceTestsWithSqlServer.cs b/Infrastructure.EFCore/Eisk.DataServices.IntegrationTests.EFCore.SqlServer/EmployeeDataServiceTestsWithSqlServer.cs
new file mode 100644
index 00000000..421513e4
--- /dev/null
+++ b/Infrastructure.EFCore/Eisk.DataServices.IntegrationTests.EFCore.SqlServer/EmployeeDataServiceTestsWithSqlServer.cs
@@ -0,0 +1,18 @@
+using Xunit;
+
+namespace Eisk.DataServices.IntegrationTests.EFCore.SqlServer;
+
+using Domains.Entities;
+using Domains.TestData;
+using Eisk.DataServices.EFCore;
+using Eisk.EFCore.Setup;
+using Test.Core.TestBases;
+
+public class EmployeeDataServiceTestsWithSqlServer : DataServiceSqlServerBaseIntegrationTests, IClassFixture
+{
+ public EmployeeDataServiceTestsWithSqlServer() : base(new EmployeeDataService(TestDbContextFactory.CreateSqlServerDbContext()), x => x.Id, new EmployeeDataFactory())
+ {
+
+ }
+
+}
diff --git a/Infrastructure.EFCore/Eisk.DomainServices.ComponentTests.EFCore/Eisk.DomainServices.ComponentTests.EFCore.csproj b/Infrastructure.EFCore/Eisk.DomainServices.ComponentTests.EFCore/Eisk.DomainServices.ComponentTests.EFCore.csproj
index 79ef495e..e3a051b1 100644
--- a/Infrastructure.EFCore/Eisk.DomainServices.ComponentTests.EFCore/Eisk.DomainServices.ComponentTests.EFCore.csproj
+++ b/Infrastructure.EFCore/Eisk.DomainServices.ComponentTests.EFCore/Eisk.DomainServices.ComponentTests.EFCore.csproj
@@ -1,13 +1,16 @@
- netcoreapp2.0
+ net6.0
-
-
-
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
diff --git a/Infrastructure.EFCore/Eisk.DomainServices.ComponentTests.EFCore/EmployeeDomainServiceComponentTests.cs b/Infrastructure.EFCore/Eisk.DomainServices.ComponentTests.EFCore/EmployeeDomainServiceComponentTests.cs
index 67e62730..7a0581d8 100644
--- a/Infrastructure.EFCore/Eisk.DomainServices.ComponentTests.EFCore/EmployeeDomainServiceComponentTests.cs
+++ b/Infrastructure.EFCore/Eisk.DomainServices.ComponentTests.EFCore/EmployeeDomainServiceComponentTests.cs
@@ -1,23 +1,23 @@
using Eisk.DataServices.EFCore;
using Eisk.Domains.Entities;
+using Eisk.Domains.TestData;
using Eisk.EFCore.Setup;
using Eisk.Test.Core.TestBases;
-namespace Eisk.DomainServices.ComponentTests.EFCore
+namespace Eisk.DomainServices.ComponentTests.EFCore;
+
+public class EmployeeDomainServiceComponentTests : DomainServiceBaseComponentTests
{
- public class EmployeeDomainServiceComponentTests : DomainServiceBaseComponentTests
+ public EmployeeDomainServiceComponentTests() :
+ base(new EmployeeDomainService(Factory_DataService()), x => x.Id, new EmployeeDataFactory())
{
- public EmployeeDomainServiceComponentTests() :
- base(new EmployeeDomainService(Factory_DataService()), x => x.Id)
- {
-
- }
- static EmployeeDataService Factory_DataService()
- {
- EmployeeDataService employeeDataService = new EmployeeDataService(TestDbContextFactory.CreateDbContext());
+ }
+
+ static EmployeeDataService Factory_DataService()
+ {
+ EmployeeDataService employeeDataService = new EmployeeDataService(TestDbContextFactory.CreateInMemoryDbContext());
- return employeeDataService;
- }
+ return employeeDataService;
}
}
diff --git a/Infrastructure.EFCore/Eisk.EFCore.Setup/DbContextDataInitializer.cs b/Infrastructure.EFCore/Eisk.EFCore.Setup/DbContextDataInitializer.cs
index 5e7bdbba..deb4d3a5 100644
--- a/Infrastructure.EFCore/Eisk.EFCore.Setup/DbContextDataInitializer.cs
+++ b/Infrastructure.EFCore/Eisk.EFCore.Setup/DbContextDataInitializer.cs
@@ -1,35 +1,34 @@
using System.Linq;
-namespace Eisk.EFCore.Setup
-{
- using Eisk.DataServices.EFCore.DataContext;
- using Domains.Entities;
- using Eisk.Test.Core.DataGen;
+namespace Eisk.EFCore.Setup;
+
+using DataServices.EFCore.DataContext;
+using Domains.TestData;
+using Eisk.Domains.Entities;
+using System.Collections.Generic;
- public static class DbContextDataInitializer
+public static class DbContextDataInitializer
+{
+ public static void Initialize(AppDbContext context)
{
- public static void Initialize(AppDbContext context)
+ context.Database.EnsureDeleted();
+
+ context.Database.EnsureCreated();
+
+ // Look for any data available.
+ if (context.Employees.Any())
{
- context.Database.EnsureDeleted();
-
- context.Database.EnsureCreated();
-
- // Look for any data available.
- if (context.Employees.Any())
- {
- return; // DB has been seeded
- }
-
- for (int i = 0; i < 10; i++)
- context.Employees.Add(
- EntityDataFactory.Factory_Entity_Instance(
- x =>
- {
- x.Id = 0;
- x.ReportsToId = null;
- }));
-
- context.SaveChanges();
+ return; // DB has been seeded
}
+
+ var employeeDataFactory = new EmployeeDataFactory();
+ var testEmployees = new List();
+
+ for (int i = 0; i < 10; i++)
+ testEmployees.Add(employeeDataFactory.Factory_Entity());
+
+ context.Employees.AddRange(testEmployees);
+ context.SaveChanges();
+
}
-}
\ No newline at end of file
+}
diff --git a/Infrastructure.EFCore/Eisk.EFCore.Setup/Eisk.EFCore.Setup.csproj b/Infrastructure.EFCore/Eisk.EFCore.Setup/Eisk.EFCore.Setup.csproj
index 3461a954..3f272837 100644
--- a/Infrastructure.EFCore/Eisk.EFCore.Setup/Eisk.EFCore.Setup.csproj
+++ b/Infrastructure.EFCore/Eisk.EFCore.Setup/Eisk.EFCore.Setup.csproj
@@ -1,14 +1,15 @@
- netcoreapp2.0
+ net6.0
-
-
+
+
+
diff --git a/Infrastructure.EFCore/Eisk.EFCore.Setup/EntityFrameworkCoreInitializer.cs b/Infrastructure.EFCore/Eisk.EFCore.Setup/EntityFrameworkCoreInitializer.cs
deleted file mode 100644
index d3b79cb7..00000000
--- a/Infrastructure.EFCore/Eisk.EFCore.Setup/EntityFrameworkCoreInitializer.cs
+++ /dev/null
@@ -1,45 +0,0 @@
-using System;
-using Eisk.DataServices.EFCore.DataContext;
-using Microsoft.AspNetCore.Hosting;
-using Microsoft.Extensions.Configuration;
-using Microsoft.Extensions.DependencyInjection;
-
-namespace Eisk.EFCore.Setup
-{
- public class EntityFrameworkCoreInitializer
- {
- public static EntityFrameworkCoreInitializer Factory(IServiceCollection services, IConfiguration configuration)
- {
- return new EntityFrameworkCoreInitializer(services, configuration);
- }
-
- private readonly IServiceCollection _services;
- private readonly IConfiguration _configuration;
- private readonly IHostingEnvironment _hostingEnvironment;
- public EntityFrameworkCoreInitializer(IServiceCollection services, IConfiguration configuration)
- {
- _services = services;
- _configuration = configuration;
-
- IServiceProvider serviceProvider = _services.BuildServiceProvider();
- _hostingEnvironment = serviceProvider.GetService();
- }
-
- public void AddDbContext()
- {
- if (_hostingEnvironment.IsDevelopment())
- _services.AddScoped();
- else
- _services.AddScoped(x => new SqlServerDbContext(_configuration));
- }
-
- public static void AddSeedDataToDbContext(IHostingEnvironment hostingEnvironment, IConfiguration configuration)
- {
- if (hostingEnvironment.IsDevelopment())
- DbContextDataInitializer.Initialize(new InMemoryDbContext());
- else
- DbContextDataInitializer.Initialize(new SqlServerDbContext(configuration));
-
- }
- }
-}
\ No newline at end of file
diff --git a/Infrastructure.EFCore/Eisk.EFCore.Setup/InMemoryDbContext.cs b/Infrastructure.EFCore/Eisk.EFCore.Setup/InMemoryDbContext.cs
index e960107e..64915def 100644
--- a/Infrastructure.EFCore/Eisk.EFCore.Setup/InMemoryDbContext.cs
+++ b/Infrastructure.EFCore/Eisk.EFCore.Setup/InMemoryDbContext.cs
@@ -1,22 +1,21 @@
-using System;
-using Eisk.DataServices.EFCore.DataContext;
+using Eisk.DataServices.EFCore.DataContext;
using Microsoft.EntityFrameworkCore;
+using System;
-namespace Eisk.EFCore.Setup
+namespace Eisk.EFCore.Setup;
+
+public class InMemoryDbContext : AppDbContext
{
- public class InMemoryDbContext : AppDbContext
+ private readonly bool _uniqueDbName;
+ public InMemoryDbContext(bool uniqueDbName = false) : base(new DbContextOptionsBuilder().Options)
+ {
+ _uniqueDbName = uniqueDbName;
+ }
+
+ protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
- private readonly bool _uniqueDbName;
- public InMemoryDbContext(bool uniqueDbName = false) : base(new DbContextOptionsBuilder().Options)
- {
- _uniqueDbName = uniqueDbName;
- }
-
- protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
- {
- var dbName = "Eisk" + (_uniqueDbName ? Guid.NewGuid().ToString() : string.Empty);
+ var dbName = "Eisk" + (_uniqueDbName ? Guid.NewGuid().ToString() : string.Empty);
- optionsBuilder.UseInMemoryDatabase(dbName);
- }
+ optionsBuilder.UseInMemoryDatabase(dbName);
}
-}
\ No newline at end of file
+}
diff --git a/Infrastructure.EFCore/Eisk.EFCore.Setup/SqlServerDbContext.cs b/Infrastructure.EFCore/Eisk.EFCore.Setup/SqlServerDbContext.cs
index dc6337eb..c987eca3 100644
--- a/Infrastructure.EFCore/Eisk.EFCore.Setup/SqlServerDbContext.cs
+++ b/Infrastructure.EFCore/Eisk.EFCore.Setup/SqlServerDbContext.cs
@@ -1,26 +1,25 @@
-using System;
-using Eisk.DataServices.EFCore.DataContext;
+using Eisk.DataServices.EFCore.DataContext;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
+using System;
-namespace Eisk.EFCore.Setup
+namespace Eisk.EFCore.Setup;
+
+public class SqlServerDbContext : AppDbContext
{
- public class SqlServerDbContext : AppDbContext
- {
- public SqlServerDbContext(IConfiguration configuration) : this(configuration.GetConnectionString("DefaultSqlConnection")) { }
+ public SqlServerDbContext(IConfiguration configuration) : this(configuration.GetConnectionString("DefaultSqlConnection")) { }
- private readonly string _connectionString;
- public SqlServerDbContext(string connectionString = null) : base(new DbContextOptionsBuilder().Options)
- {
- if (string.IsNullOrEmpty(connectionString))
- throw new ArgumentNullException(nameof(connectionString));
+ private readonly string _connectionString;
+ public SqlServerDbContext(string connectionString = null) : base(new DbContextOptionsBuilder().Options)
+ {
+ if (string.IsNullOrEmpty(connectionString))
+ throw new ArgumentNullException(nameof(connectionString));
- _connectionString = connectionString;
- }
+ _connectionString = connectionString;
+ }
- protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
- {
- optionsBuilder.UseSqlServer(_connectionString);
- }
+ protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
+ {
+ optionsBuilder.UseSqlServer(_connectionString);
}
-}
\ No newline at end of file
+}
diff --git a/Infrastructure.EFCore/Eisk.EFCore.Setup/TestDbContextFactory.cs b/Infrastructure.EFCore/Eisk.EFCore.Setup/TestDbContextFactory.cs
index 31c990fa..9a7f233c 100644
--- a/Infrastructure.EFCore/Eisk.EFCore.Setup/TestDbContextFactory.cs
+++ b/Infrastructure.EFCore/Eisk.EFCore.Setup/TestDbContextFactory.cs
@@ -1,12 +1,16 @@
using Eisk.DataServices.EFCore.DataContext;
-namespace Eisk.EFCore.Setup
+namespace Eisk.EFCore.Setup;
+
+public static class TestDbContextFactory
{
- public static class TestDbContextFactory
+ public static AppDbContext CreateInMemoryDbContext()
+ {
+ return new InMemoryDbContext(true);
+ }
+
+ public static AppDbContext CreateSqlServerDbContext()
{
- public static AppDbContext CreateDbContext()
- {
- return new InMemoryDbContext(true);
- }
+ return new SqlServerDbContext("Server=(localdb)\\mssqllocaldb;Database=eisk;Trusted_Connection=True;MultipleActiveResultSets=true");
}
-}
\ No newline at end of file
+}
diff --git a/LICENSE b/LICENSE.txt
similarity index 97%
rename from LICENSE
rename to LICENSE.txt
index b085c81b..385621f3 100644
--- a/LICENSE
+++ b/LICENSE.txt
@@ -1,6 +1,6 @@
MIT License
-Copyright (c) 2019 EISK
+Copyright (c) 2022 EISK
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/Notes/Business-Rules.txt b/Notes/Business-Rules.txt
new file mode 100644
index 00000000..e901bf59
--- /dev/null
+++ b/Notes/Business-Rules.txt
@@ -0,0 +1,18 @@
+========================================================
+Business Rules
+========================================================
+* Single Field Level (Property)
+ * Required
+ * Length
+ * Regular Expression (phone, email)
+* Single Field Level (Logic)
+ * Birthday should not be future date
+ * Employee must be 18 years old
+* Multiple Field Level
+ * HireDate should be later than Birthday
+* DB Check on Same Table
+ * Email should be unique
+* DB Check on Foreign Key Table
+ * An employee can have atmost 10 reports
+========================================================
+
diff --git a/Notes/Dev-Set-up.txt b/Notes/Dev-Set-up.txt
new file mode 100644
index 00000000..9438b157
--- /dev/null
+++ b/Notes/Dev-Set-up.txt
@@ -0,0 +1,40 @@
+======================================================
+Template
+======================================================
+* Debugging template creation
+* Render template locally
+ * Run /build/dnn-install-from-local.cmd
+
+
+References
+* https://devblogs.microsoft.com/dotnet/how-to-create-your-own-templates-for-dotnet-new/
+* https://github.com/dotnet/dotnet-template-samples
+
+======================================================
+SQL Server
+======================================================
+Setting up Local DB in local environment
+
+* You would like to know the version of your SQL Server LocalDB instance.
+ * Open "Command Prompt"
+ * Type line "sqllocaldb info" and check the name. By default, it will show "MSSQLLocalDB".
+ * Type line "sqllocaldb info MSSQLLocalDB"
+ * If the version is "12.0.4100.1", LocalDB instance is in 2014 version. If the version if "13.1.4100.0" is in 2016 version.
+
+* Starting LocalDB
+ * sqllocaldb start MSSQLLocalDB
+
+* Connect with SQL Server Management Studio
+ * Server name: (localdb)\mssqllocaldb
+
+* Installing
+* Deploying database schema
+* Set connection string
+
+======================================================
+ASP.NET / Web Server
+======================================================
+
+* Turn off development mode for ASP.NET
+
+========================================================
diff --git a/Notes/Eisk-Features.txt b/Notes/Eisk-Features.txt
new file mode 100644
index 00000000..d1e2ada3
--- /dev/null
+++ b/Notes/Eisk-Features.txt
@@ -0,0 +1,20 @@
+User Stories
+
+* To be added
+
+Project Features
+
+* Web API base classes with supported in-memory web tests
+* Swagger support
+* Exception handling classes and filters
+
+* Domain class example with property attribute, inheritance, value object and enumeration support
+
+* Domain Service base classes with supported base component tests with in-memory databases
+
+* Data Service base classes with supported base integration tests with sql server databases
+
+* Meaningful test data generators
+
+* DevOps pipeline to build and run tests
+* DevOps pipeline to deploy in azure app services
diff --git a/Notes/Entity-Samples.txt b/Notes/Entity-Samples.txt
new file mode 100644
index 00000000..6e8ad32c
--- /dev/null
+++ b/Notes/Entity-Samples.txt
@@ -0,0 +1,64 @@
+========
+Samples Use Cases (platform agonistic)
+
+* Different samples for same employee entity to illustrate how to use eisk differently as per design choices.
+* The respective sample will be loaded as provided in the optional parameter when creating project from template.
+* A default sample will be loaded when no option is provided.
+========
+
+* Empty (no domain)
+
+Single Entity (Base Classes)
+
+* Minimal code domain crud - Web controller base, with generic domain and data service
+
+* All base classes (no custom rules)
+* (default) All base classes (with custom rules)
+
+Single Entity (No Base Classes)
+- using service utility class as property instead of using as base class
+
+* No base classes (with no custom rules and partial crud) - for instance create and get only
+* No base classes (with custom rules and partial crud) - for instance create and get only
+
+* No base classes (with no custom rules and all crud)
+* No base classes (with custom rules and all crud)
+
+View Model (Base Classes)
+
+* With base classes, single view model, no custom rules
+* With base classes, single view model, with custom rules
+
+* With base classes, editor + view model, no custom rules
+* With base classes, editor + view model, with custom rules
+
+View Model (With out Base Classes)
+
+* With out base classes, single view model, no custom rules
+* With out base classes, single view model, with custom rules
+
+* With out base classes, editor + view model, no custom rules
+* With out base classes, editor + view model, with custom rules
+
+Search, Filtering, Sortng, Paging
+
+* Search
+* Filtering
+* Paging
+* Sorting
+
+Multiple Entities
+
+* 1:m
+* m:1
+* m:m
+
+Query Features
+
+* Raw text query
+* Aggregate query (count, sum)
+* Stored procedure
+* Db function
+* View
+========
+
diff --git a/Notes/Modules.txt b/Notes/Modules.txt
new file mode 100644
index 00000000..c4d4ff5a
--- /dev/null
+++ b/Notes/Modules.txt
@@ -0,0 +1,111 @@
+========================================================
+Core Modules and Releases
+
+Client Side
+* React (default)
+* Blazor
+* React Native
+
+Web API Layer
+* WebApi - ASP.NET Web API (default)
+* WebApi.Azure - Azure Function (http)
+* gRPC - gRPC
+* GraphAPI - Graph API
+
+Domain Layer
+* Clean Architecture (default)
+* DDD
+* CQRS
+
+Data Service Layer Interface
+* Persistence ignorant interface
+
+Data Access Layer
+* Entity Framework (default)
+* Dapper
+* NHibernate
+
+Data Storage (in-memory)
+* Memory: EF In-memory (default)
+* Memory: SQLLite In-memory
+
+Data Storage
+* RDBMS: SQL Server (default)
+* Key-Value Pair: Azure Table Storage
+* Document database: COSMOS
+* Document database: Couchbase
+* Graph database: COSMOS (gremline)
+* Graph database: Neo4J
+* Columnar database: Cassandra
+
+===========================================
+Cross Cutting Concerns and Services
+
+Authentication
+* Azure AD B2C
+* Azure AD
+* Identity Server
+* ASP.NET Identity
+* Auth0
+
+Logging
+* Log4Net
+* SeriLog
+* Azure Insight
+
+Caching
+* Redis
+* Couchbase
+* SQL Server In-memory
+
+Search
+* Azure Search
+
+Backgeound Process
+* Process.AzureWebJob
+* Process.AzureLogicApp
+* ServerLess.AzureFunction (Scheduler) (default)
+* ServerLess.AWSLambda
+
+Messagging
+* Azure Storage Queue
+* Azure Service Bus
+* AWS Simple Queue Service
+
+Hosting
+* Azure App Services
+* AWS
+* Docker
+* Kubernetes
+
+DevOps
+* AzureDevOps
+* Github Actions
+* Vercel
+
+========================================================
+Repo Modules and Dependencies
+
+- eisk.template (default)
+
+- eisk.webapi (output repo)
+- eisk.template.webapi (template sub module or main module)
+
+- eisk.domain-services
+- eisk.data-services (default)
+- eisk.data-services.sql-server
+- eisk.data-services.cosmosdb
+
+- eisk.test-core (default shared across all, can be used as sub-module or main module)
+- eisk.core (default shared across all, can be used as sub-module or main module)
+
+========================================================
+EISK Version History
+
+v9.0 - Web API Edition .NET 6.0 VS2022, 17.0.32112.339 - 10.0.40219.1
+v8.0 - Web API Edition .NET Core 2.0 VS2017, 15.0.28307.168 - 10.0.40219.1 (Core V1.0)
+v7.0 - MVC Edition .NET 4.5.1 VS2013, 12.0.21005.1 - 10.0.40219.1
+v6.0 - MVC Edition .NET 4.0 VS2012, 11.0
+v5.0 - Web Form Edition .NET 4.0 VS2010, 10.0
+
+========================================================
diff --git a/Notes/Release-Instructions.txt b/Notes/Release-Instructions.txt
new file mode 100644
index 00000000..ee9b4345
--- /dev/null
+++ b/Notes/Release-Instructions.txt
@@ -0,0 +1,53 @@
+========================================================
+Update a Version:
+
+Eisk.WebApi.TemplatePack
+ * Eisk.WebApi.proj
+ * source.extension.vsixmanifest
+Eisk.WebApi
+ * Program.cs (for Swagger doc)
+========================================================
+Release A New Version
+
+Release Prep
+* Update version in code and package
+* Build the project in CI
+
+Releasing the Web Site (semi-manual)
+* Release will be created automatically
+* Staging - will be deployed automatically
+* Prod - Web site needs to be deployed manually
+
+Releasing in git repo (semi-manual)
+* Release will be created automatically
+* Cd will deploy the changes in version branch automatically
+* Version branch needs to be merged manually
+
+Releasing in Nuget (semi-manual)
+* Release will be created automatically
+* Release needs to be deployed by manual trigger (as nuget releases immutable i.e. canreleasepdated once created)
+
+Releasing to VS Gallery (semi-manual)
+* Release will be created automatically
+* Deploy need to be triggered manually
+
+Releasing in Github Release (manual) - Create Tag
+* ** Merge the repo master branch (mentioned above) **
+* Create tag in github
+* Create release in github from the created tag
+* Update version in DevOps release
+* Create release and trigger deploy manually
+ * Template repo project readme.md will be included automatically in the release notes.
+ * Respective release assests as menionted in DevOps rlease will be updated automatically when master branch changed.
+
+Releasing in Github Release (manual) - Update Tag in Existing Release
+* Go to the corresponding release
+* Create a new tag from the release page (based on target commit)
+* Update version in DevOps release
+* Create release and trigger deploy manually
+
+Releasing in Github Release (manual) - Update Content
+* Relase Created Automatically
+* Trigger deploy manually (it doesn't update the source in the release, but updates the contents (notes, binaries in release page)
+
+========================================================
diff --git a/Notes/TODO.txt b/Notes/TODO.txt
new file mode 100644
index 00000000..45fe14d7
--- /dev/null
+++ b/Notes/TODO.txt
@@ -0,0 +1,157 @@
+========================================================
+TODO: Today
+
+DONE * Include nuge badge
+DONE * Include support help for stackoverflow
+DONE * Update git repo as template
+DONE N/A * Apply rules logic in custom data generator
+
+* Update project image in read me
+* Include github badge
+* Include uptime robot badge
+* Include readme for nuget package
+* Fix nuget package warnings
+
+* Re-visit exception classes
+* review template documentations
+ * check rendered output for template with VS
+ * check conditional rendering (file)
+ * check conditional rendering (text)
+
+========================================================
+TODO:
+
+CI (Remote)
+
+* Rename eisk.webapi.template to eisk.template
+* Convert generated template CI to Yml
+
+CD (Remote)
+
+DONE * Integrate with with git release task
+* Publish to VS Gallery
+* Create staging api app service for V8
+
+Build / packagaing
+
+Code
+
+R * Custom logic
+ * Apply custom business logic
+ * Add field for email
+ * Add field for URL
+R * Error handling
+ * Added exception handler for controller
+ * Implement http error on exception for controller
+ * Firing exception when field constraint (i.e. length) is not applied
+R * Log
+ * Add log functionality
+ * Integrate azure insight
+
+* Include view model example
+
+Testing
+
+R * Add web tests
+ * Employee web tests
+ * Web test base class
+* Set db fixture with assesbmly set-up
+* Sql server integration tests: load from config
+* Create postman based test file (for template only)
+* Test post and update methods
+* Include ORM tests
+* Identify test strategy, check base tests usability
+
+Release Tasks
+
+DONE * Merge V9.0 branch to master
+DONE * Publish nuget package to nuget gallery
+DONE * Publish documentation (soft release)
+
+* Publish to VS Gallery
+DONE * Experiement tag, release and branch (what happens when branch is deleted after release is created?)
+
+Others
+
+* Explore new .net features
+* Include instruction for template build and publish
+* Rename Eisk.DomainServices.ComponentTests.EFCore -> Eisk.DomainServices.ComponentTests?
+
+========================================================
+Phases
+
+DONE * Upgrade Template Pack to .NET 6.0
+DONE * Complete CI/CD - for V8, nuget, git repo, app service
+DONE * Complete CI/CD - for V9 git repo, app service
+DONE * Complete CI/CD - for Docs
+DONE * Restructure (docs) - build locally, folder structure, navigations (individual top, top nav, breadcrumbs)
+
+* Custom development (template) - build locally, document process, custom logic implementation
+* Doc - initial documenation
+* Blog - release post
+* Blog - tutorial
+* VSIX Release - CD, documentation
+* Github Release - CD, documentation
+* Doc - advansed documentation
+
+========================================================
+TODO: ARCHIVE
+
+Fix CI (Remote)
+DONE R * Create new doc CI/CD
+DONE * Fix github connection
+DONE * Install Github App in Azure
+DONE * Fix CI issue (core)
+DONE * Fix CI issue (template)
+DONE * Fix CI issue (docs)
+DONE * Finalize repo structure
+
+Fix CD (Remote)
+DONE * Update CI for Windows-2022 (V9, V8 Docs)
+DONE * Update all CD for Windows-2022
+DONE * Fix publish to git repo (V9) - exclude binaries check-in
+DONE * Fix publish to git repo (V8) - exclude binaries check-in
+DONE * Publish to git repo (V9)
+DONE * Publish to git repo (V8)
+DONE * Fix Azure Web (Staging)
+DONE * Fix Azure Web (Prod)
+DONE * Fix Nuget publish (.new new)
+DONE * Update version specific trigger for CD
+DONE * Update version specific trigger for CD
+DONE * Create new app service for v9
+DONE * Deploy to web service v9
+DONE * Fix deploy to web service v8
+
+Build / packagaing
+DONE * generate template from nuget package
+DONE * Run docs locally
+DONE * Fix local run (web api) v8
+DONE * Fix local run (web api) v9
+
+Code
+DONE * Convert to file scope namespace
+DONE * Apply title, extension in entity data generator
+DONE * Investigate with length field is not causing issue when saving (for in-memory db constraints not applied)
+DONE * Remove obsolete methods (for .NET 6.0)
+DONE * fix unit tests
+DONE * Remove sub-module
+DONE * Fix project load issue for rendered content. issue: long file path
+DONE * Exclude unused project files (test projects)
+DONE * Exclude unused project files (notes)
+
+Testing
+DONE * Refactor entity data generator with domain
+DONE * Refactor entity test data generator as an abstract class
+DONE * Test data service with sql server local instance
+DONE * Complete custom data generator implementation
+DONE * Test string size implementor
+DONE * Include custom entity data factory in entity test base
+DONE * Add test data generator for employee (with meaningful sample data)
+
+Release Tasks
+DONE * Update readme.md
+
+Others
+DONE * Finalize versioning
+
+========================================================
diff --git a/Notes/Test-Strategy.txt b/Notes/Test-Strategy.txt
new file mode 100644
index 00000000..a34269ca
--- /dev/null
+++ b/Notes/Test-Strategy.txt
@@ -0,0 +1,70 @@
+========================================================
+Test Strategy
+
+Api Controller Tests
+ * In-memory web tests
+ * All http codes tests only (200, 404)
+ * Can be used with build server
+Domain Service Tests
+ * In-memory tests (default): for smaller projects (assumes empty database in each test case)
+ * Unit tests: for large projects
+ * Tests only the business rules
+ * Can be used with build server
+Data Service Tests:
+ * SQL Server integration tests (not included in solution by default)
+ * Tests all database queries/operations
+ * To be used in post-deployment (in dev/UAT environment)
+ * To be used with empty sql server with test seed data (in dev envrionment)
+ * To be used with existing sql server with test seed data (in UAT envrionment) - smoke tests only
+
+System Tests:
+ * Health check
+ ** to be tested locally, dev, prod
+ ** Includes db configuration tests
+ ** Any other external dependencies, like email server, blob storage
+ ** Can inlcude asp.net core feature, azure feature
+========================================================
+Reasons to consider testing base integration tests
+
+Sql Server (in-memory)
+- To verify if the ORM data model is not breaking (unsupported binding)
+- To verify if the ORM is working as expected (may not be needed if ORM documentation is available)
+
+Sql Server (generated from ORM)
+- To verify if the ORM data model is not breaking (unsupported binding)
+- To verify if the ORM is working as expected (may not be needed if ORM documentation is available)
+- To verify if the valid test data working (column size)
+
+Sql Server (live environment)
+- To check if the schema is same (can be achieved via schema comparison tool)
+- To check if the functionality is working as expected even if schema and database version is not identical
+
+========================================================
+========================================================
+Testing ORM functionality in test core
+
+- Single entity crud
+
+- p: Create/Create: primary and foreign tables together
+- p: Update/Create: exiting primary, create new fk row
+- p: Update/Remove: existing primary, remove existing fk row
+- p: Update/Update: updating pk and fk rows
+- p: Remove/Remove: deleting pk willl remove all fk
+- p: Remove/Update: deleting pk will update reference in fk only (no other update in fk table)
+- p: Read/Read (eager): loading pk will load all fk
+- p: Read/Read (lazy): loading pk will not not fk until property called
+
+- the above behaviour is when saving pk and its impact on fk
+- need to check the impact for the same behaviours on pk when fk is being saved
+
+- Difference between fk property and fk object
+=====≈========
+Factors
+
+* In-memory database tests (in CI)
+* In-memory web tests (in CI)
+* Database tests (in CD)
+* Web UI Tests (in CD)
+* Generic utility base classes
+========================================================
+
diff --git a/Notes/Troubleshoot.txt b/Notes/Troubleshoot.txt
new file mode 100644
index 00000000..71e89ca6
--- /dev/null
+++ b/Notes/Troubleshoot.txt
@@ -0,0 +1,23 @@
+========================================================
+CD Troubleshoot
+
+VS2022/.NET 6.0
+* Change VS2017 hosting to azure pipeline,
+ * Resolution: change in the edit release -> app service
+* Error on Deployment,
+ * Resolution: change App Plan from Linux to Windows
+* Issue: web api not showing after deployment
+ * the api json was available, but the issue was due to swagger is not being accessible: https://stackoverflow.com/questions/55658948/asp-net-core-api-get-404-on-azure-app-service-but-works-ok-on-localhost
+* Issue: App service not being deployed
+ * Error: Web Deploy cannot modify the file 'Eisk.Core.dll' on the destination because it is locked by an external process. In order to allow the publish operation to succeed, you may need to either restart your application to release the lock, or use the AppOffline rule handler for .Net applications on your next publish attempt. Learn more at: http://go.microsoft.com/fwlink/?LinkId=221672#ERROR_FILE_IN_USE. Learn more at: https://go.microsoft.com/fwlink/?LinkId=221672#ERROR_FILE_IN_USE. Error count: 1.
+ * Solution: In Azure DevOps, releas task for app service, set, Use Offline settings as true
+
+VS2017/.NET 2.0
+* Issue: An error occurred while starting the application. .NET Core 4.6.26614.01 X86 v4.0.0.0 Microsoft.AspNetCore.Hosting version 2.0.3-rtm-10026 | Microsoft Windows 10.0.14393
+ * Enable detailed errors in azure portal: https://stackoverflow.com/questions/47134657/azure-webapp-asp-net-core-2-error-an-error-occurred-while-starting-the-applicat
+* Issue: Could not load file or assembly 'System.Runtime, Version=6.0.0.0
+ * In the build use specific .net sdk (2.0.0): https://stackoverflow.com/questions/59474379/failed-to-use-net-sdk-agent-in-azure-devops-build-pipeline
+ * Delete and re-create app service with .NET 3.1/2.1 LTS
+
+========================================================
+
\ No newline at end of file
diff --git a/README.md b/README.md
index f39fa5e7..4d94bcd6 100644
--- a/README.md
+++ b/README.md
@@ -1,10 +1,7 @@
-[![Build status](https://dev.azure.com/EiskOps/Eisk/_apis/build/status/Eisk-WebApi-TemplatePack-CI)](https://dev.azure.com/EiskOps/Eisk/_build/latest?definitionId=3) [![BuitlWithDot.Net shield](https://builtwithdot.net/project/334/eisk/badge)](https://builtwithdot.net/project/334/eisk)
-
+[![NuGet Badge](https://buildstats.info/nuget/Eisk.WebApi)](https://www.nuget.org/packages/Eisk.WebApi/) [![Build status](https://dev.azure.com/EiskOps/Eisk/_apis/build/status/Eisk-WebApi-TemplatePack-CI)](https://dev.azure.com/EiskOps/Eisk/_build/latest?definitionId=3) [![BuitlWithDot.Net shield](https://builtwithdot.net/project/334/eisk/badge)](https://builtwithdot.net/project/334/eisk)
...
-# Getting Started with EISK Web Api
-
-EISK makes it easy to write scalable and secured web api on top of Microsoft's new cutting edge .net core technologies.
+EISK makes it easy to write scalable and secured web api on top of Microsoft's new cutting edge .net based technologies.
With an optional set of customizable utility classes, samples and tools, it lets you creating new web api straight away without wide technical experience or learning curve.
@@ -12,33 +9,44 @@ With an optional set of customizable utility classes, samples and tools, it lets
If you like or are using this project to learn or start your solution, please give it a [star](https://github.com/EISK/eisk.webapi). Thanks!
-![eisk web api](https://github.com/EISK/eisk/blob/master/eisk-webapi-small.png)
+## Core Technologies
+
+* Platform: [.NET Framework 6.0](https://devblogs.microsoft.com/dotnet/announcing-net-6/) - The Fastest .NET Yet!
+* Web Framework: ASP.NET Web API
+* ORM Framework: Entity Framework
+* Programming Language: C#
## Sample Use Case
-Using a simple table entity 'Employee' it demonstrates all aspect of web development including layered architecture following DDD, micro service, unit and integration tests, building and deploying in cloud environment.
+Using a simple data entity 'Employee', EISK shows how we can build scalable web api's easily along with addressing real-world domain and business use cases, including:
+
+* [C]reating a new employee record
+* [R]ead existing employee records
+* [U]pdate an existing employee record
+* [D]elete an existing employee record
-Here is a simple CRUD use case illustrated in the default template:
+![eisk web api](https://github.com/EISK/eisk/blob/master/eisk-webapi-small.png)
-* Creating a new employee record
-* Read existing employee records
-* Update an existing employee record
-* Delete existing employee records
+Check the [Live Demo](https://eisk-webapi.azurewebsites.net) to see the use case implementation in action.
-## Core Technology Areas
+## Dev Features
-* ASP.NET Core (Web Api)
-* Entity Framework Core
-* C#
-* Visual Studio
-* Azure App Services
+You can build your own RESTful web api using EISK's Visual Studio and ASP.NET Web API project template.
-## System Requirements (Development)
+The template includes (but not limited to), project structure and all utility classes mentioned below to enable building modern cloud-aware RESTful APIs.
-* Visual Studio 2017 ([Free](https://visualstudio.microsoft.com/vs/community/) Community Edition or higher)
+* **Clean Architecture** based implementation
+* **Swagger/OpenAPI** based RESTful Web API, including resuable base classes
+* **Base classes** for common CRUD functionalities and testing for logical layers (i.e. controller, domain, data layers)
+* **Utility classes** to generate real-world test data
+* Support for database integration tests with both in-memory database and SQL server
## QuickStart Guide
+Before installing EISK, all you need to have the following Visual Studio version installed.
+
+* Visual Studio 2022 ([Free](https://visualstudio.microsoft.com/vs/community/) Community Edition or higher)
+
Getting started with EISK Web Api is pretty easy.
You can either [clone](https://github.com/EISK/eisk.webapi.git) from github or simply run the following `dotnet new` command in command prompt to create a new project from EISK:
@@ -50,6 +58,10 @@ Once the contents are available, just open the created solution, select "Eisk.We
That's it!
+### How About Old Versions?
+
+If you want to continue using one of the older versions of EISK, check the [releases](https://github.com/EISK/eisk.webapi/releases) page for specific instructions to install and use older versions of EISK.
+
## What's Next?
After running the created project successfully, you'll get an understanding about how the sample use case has been used to explore cutting edge technologies for building a web api.
@@ -58,7 +70,11 @@ Next - you can try some hands-on experience by creating your own api on top of y
Utilities and code samples as provided in EISK have intentionally been designed to be self explaining. You may still want to get deeper understanding by exploring the documentations:
-* [Live Demo](https://eiskwebapi.azurewebsites.net)
-* [Hands-on Walk-through](https://eisk.github.io/eisk.webapi/docs/application-development/handson-walkthrough-create-service-api.html)
-* [Logical Layer Architecture](https://eisk.github.io/eisk.webapi/docs/architecture/logical-layers.html)
-* [Technology Stack](https://eisk.github.io/eisk.webapi/docs/technical-reference/technology-stack.html)
+* [Live Demo](https://eisk-webapi.azurewebsites.net)
+* [Hands-on Walk-through](https://eisk.github.io/docs/webapi/application-development/handson-walkthrough-create-service-api.html)
+* [Logical Layer Architecture](https://eisk.github.io/docs/webapi/architecture/logical-layers.html)
+* [Technology Stack](https://eisk.github.io/docs/webapi/technical-reference/technology-stack.html)
+
+## Questions?
+
+Should you have any questions or need any help to implement new cool features, you can [ask](https://stackoverflow.com/questions/ask?tags=eisk,webapi,asp.net-core&title=In%20EISK,%20How%20Do%20We%20..) in StackOverflow community with tag [eisk](https://stackoverflow.com/questions/tagged/eisk) and get prompt response.
diff --git a/WebApi/Eisk.WebApi/Controllers/EmployeesController.cs b/WebApi/Eisk.WebApi/Controllers/EmployeesController.cs
index 86de7260..b4cf12e8 100644
--- a/WebApi/Eisk.WebApi/Controllers/EmployeesController.cs
+++ b/WebApi/Eisk.WebApi/Controllers/EmployeesController.cs
@@ -1,14 +1,16 @@
-namespace Eisk.WebApi.Controllers
-{
- using Eisk.Core.WebApi;
- using Domains.Entities;
- using DomainServices;
+namespace Eisk.WebApi.Controllers;
+
+using Core.WebApi;
+using Domains.Entities;
+using DomainServices;
+using Microsoft.AspNetCore.Mvc;
- public class EmployeesController : WebApiControllerBase
+[ApiController]
+[Route("[controller]")]
+public class EmployeesController : WebApiControllerBase
+{
+ public EmployeesController(EmployeeDomainService employeeDomainService) : base(employeeDomainService)
{
- public EmployeesController(EmployeeDomainService employeeDomainService):base(employeeDomainService)
- {
-
- }
+
}
}
diff --git a/WebApi/Eisk.WebApi/Eisk.WebApi.csproj b/WebApi/Eisk.WebApi/Eisk.WebApi.csproj
index 2cb8a91e..c900c905 100644
--- a/WebApi/Eisk.WebApi/Eisk.WebApi.csproj
+++ b/WebApi/Eisk.WebApi/Eisk.WebApi.csproj
@@ -1,23 +1,13 @@
-
+
- netcoreapp2.0
+ net6.0
+ enable
+ enable
-
-
-
-
-
-
-
-
-
-
-
-
-
+
diff --git a/WebApi/Eisk.WebApi/Program.cs b/WebApi/Eisk.WebApi/Program.cs
index baf704e3..75841567 100644
--- a/WebApi/Eisk.WebApi/Program.cs
+++ b/WebApi/Eisk.WebApi/Program.cs
@@ -1,18 +1,64 @@
-using Microsoft.AspNetCore;
-using Microsoft.AspNetCore.Hosting;
+using Eisk.Core.DataService;
+using Eisk.Core.DataService.EFCore;
+using Eisk.Core.DomainService;
+using Eisk.DataServices.EFCore;
+using Eisk.DataServices.EFCore.DataContext;
+using Eisk.DataServices.Interfaces;
+using Eisk.DomainServices;
+using Eisk.EFCore.Setup;
+using Microsoft.OpenApi.Models;
-namespace Eisk.WebApi
+var builder = WebApplication.CreateBuilder(args);
+
+// Add services to the container.
+
+builder.Services.AddControllers();
+// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
+builder.Services.AddEndpointsApiExplorer();
+builder.Services.AddSwaggerGen(c =>
{
- public class Program
+ c.SwaggerDoc("v1", new OpenApiInfo
{
- public static void Main(string[] args)
+ Title = "Eisk.WebApi",
+ Version = "v9.0.10",
+ Description = "EISK makes it easy to write scalable and secured web api on top of Microsoft's new cutting edge .net core technologies.",
+ Contact = new OpenApiContact
{
- BuildWebHost(args).Run();
+ Name = "EISK Web Api",
+ Email = string.Empty,
+ Url = new Uri("https://eisk.github.io")
}
+ });
+});
+
+//generic services
+
+builder.Services.AddScoped(typeof(IEntityDataService<>), typeof(EntityDataService<>));
+builder.Services.AddScoped(typeof(DomainService<,>));
+
+//custom services
+
+builder.Services.AddScoped();
+builder.Services.AddScoped();
+builder.Services.AddScoped();
+
+DbContextDataInitializer.Initialize(new InMemoryDbContext());
+
+var app = builder.Build();
+
+// Configure the HTTP request pipeline.
+app.UseSwagger();
+app.UseSwaggerUI(options =>
+{
+ options.SwaggerEndpoint("/swagger/v1/swagger.json", "v2");
+ options.RoutePrefix = string.Empty;
+});
+
+
+app.UseHttpsRedirection();
+
+app.UseAuthorization();
+
+app.MapControllers();
- public static IWebHost BuildWebHost(string[] args) =>
- WebHost.CreateDefaultBuilder(args)
- .UseStartup()
- .Build();
- }
-}
+app.Run();
diff --git a/WebApi/Eisk.WebApi/Startup.cs b/WebApi/Eisk.WebApi/Startup.cs
deleted file mode 100644
index fc23e7b4..00000000
--- a/WebApi/Eisk.WebApi/Startup.cs
+++ /dev/null
@@ -1,94 +0,0 @@
-using Eisk.Core.DataService.EFCore;
-using Microsoft.AspNetCore.Builder;
-using Microsoft.AspNetCore.Hosting;
-using Microsoft.EntityFrameworkCore;
-using Microsoft.Extensions.Configuration;
-using Microsoft.Extensions.DependencyInjection;
-using Swashbuckle.AspNetCore.Swagger;
-
-namespace Eisk.WebApi
-{
- using Core.DataService;
- using Core.DomainService;
- using Eisk.DataServices.EFCore;
- using Eisk.DataServices.EFCore.DataContext;
- using DataServices.Interfaces;
- using DomainServices;
- using EFCore.Setup;
-
- public class Startup
- {
- public Startup(IHostingEnvironment env, IConfiguration configuration)
- {
- Configuration = configuration;
-
- DbContextDataInitializer.Initialize(new InMemoryDbContext());
- }
-
- public IConfiguration Configuration { get; }
-
- // This method gets called by the runtime. Use this method to add services to the container.
- public void ConfigureServices(IServiceCollection services)
- {
- //generic services
-
- services.AddScoped();
-
- services.AddScoped(typeof(IEntityDataService<>), typeof(EntityDataService<>));
-
- services.AddScoped(typeof(DomainService<,>));
-
- //custom services
-
- services.AddScoped();
-
- services.AddScoped();
-
- services.AddScoped();
-
- services.AddMvc();
-
- // Register the Swagger generator, defining 1 or more Swagger documents
-
- services.AddSwaggerGen(c =>
- {
- c.SwaggerDoc("v1", new Info
- {
- Title = "Eisk.WebApi",
- Version = "v1.0-preview-1",
- Description = "EISK makes it easy to write scalable and secured web api on top of Microsoft's new cutting edge .net core technologies.",
- Contact = new Swashbuckle.AspNetCore.Swagger.Contact
- {
- Name = "EISK Web Api",
- Email = string.Empty,
- Url = "https://eisk.github.io/eisk.webapi"
- }
- });
- });
-
- }
-
-
- // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
- public void Configure(IApplicationBuilder app, IHostingEnvironment env)
- {
- if (env.IsDevelopment())
- {
- app.UseDeveloperExceptionPage();
- }
-
- // Enable middleware to serve generated Swagger as a JSON endpoint.
- app.UseSwagger();
-
- // Enable middleware to serve swagger-ui (HTML, JS, CSS, etc.),
- // specifying the Swagger JSON endpoint.
- app.UseSwaggerUI(c =>
- {
- c.SwaggerEndpoint("/swagger/v1/swagger.json", "Eisk.WebApi");
- c.RoutePrefix = string.Empty;
- });
-
- app.UseMvc();
- }
- }
-}
diff --git a/WebApi/Eisk.WebApi/appsettings.Development.json b/WebApi/Eisk.WebApi/appsettings.Development.json
index fa8ce71a..0c208ae9 100644
--- a/WebApi/Eisk.WebApi/appsettings.Development.json
+++ b/WebApi/Eisk.WebApi/appsettings.Development.json
@@ -1,10 +1,8 @@
-{
+{
"Logging": {
- "IncludeScopes": false,
"LogLevel": {
- "Default": "Debug",
- "System": "Information",
- "Microsoft": "Information"
+ "Default": "Information",
+ "Microsoft.AspNetCore": "Warning"
}
}
}
diff --git a/WebApi/Eisk.WebApi/appsettings.json b/WebApi/Eisk.WebApi/appsettings.json
index c85ef4af..10f68b8c 100644
--- a/WebApi/Eisk.WebApi/appsettings.json
+++ b/WebApi/Eisk.WebApi/appsettings.json
@@ -1,12 +1,9 @@
-{
- "ConnectionStrings": {
- "DefaultSqlConnection": "Server=(localdb)\\mssqllocaldb;Database=EiskDb;Trusted_Connection=True;MultipleActiveResultSets=true"
- },
-
+{
"Logging": {
- "IncludeScopes": false,
"LogLevel": {
- "Default": "Warning"
+ "Default": "Information",
+ "Microsoft.AspNetCore": "Warning"
}
- }
+ },
+ "AllowedHosts": "*"
}
diff --git a/build/git-bash-echo.sh b/build/git-bash-echo.sh
new file mode 100644
index 00000000..f0495bd0
--- /dev/null
+++ b/build/git-bash-echo.sh
@@ -0,0 +1,29 @@
+echo "############################# Passed Params (before) 1 - $1, 2 - $2, 3 - $3, 4 - $4, 5 - $5 6 - $6"
+
+ContentTargetGitAddress=${1:-https://github.com/EISK/eisk.webapi.git}
+echo "############################# ContentTargetGitAddress ContentTargetGitAddress"
+
+ContentTargetGitUserName=${2:-AshrafAlam}
+echo "############################# ContentTargetGitUserName $ContentTargetGitUserName"
+
+ContentTargetGitUserEmail=${3:-joycsc@gmail.com}
+echo "############################# ContentTargetGitUserEmail $ContentTargetGitUserEmail"
+
+ContentSrc=${4:-content}
+echo "############################# ContentSrc $ContentSrc"
+
+ContentTargetGitBranch=${5:-content-branch}
+echo "############################# ContentTargetGitBranch $ContentTargetGitBranch"
+
+ContentTargetGitRepoDownloadFolder="content-repo"
+echo "############################# ContentTargetGitRepoDownloadFolder (where content will be pushed) $ContentTargetGitRepoDownloadFolder"
+
+echo "############################# PWD $PWD"
+
+SOURCE_DIR=$PWD
+echo "############################# SOURCE_DIR $SOURCE_DIR"
+
+TEMP_REPO_DIR=$PWD/$ContentTargetGitRepoDownloadFolder
+echo "############################# TEMP_REPO_DIR $TEMP_REPO_DIR"
+
+echo "############################# Passed Params (after) 1 - $1, 2 - $2, 3 - $3, 4 - $4, 5 - $5 6 - $6"
\ No newline at end of file
diff --git a/build/git-push.sh b/build/git-push.sh
index 1bf150c7..c24e8bc6 100644
--- a/build/git-push.sh
+++ b/build/git-push.sh
@@ -1,11 +1,11 @@
ContentTargetGitAddress=${1:-https://github.com/EISK/eisk.webapi.git}
ContentTargetGitUserName=${2:-AshrafAlam}
-ContentTargetGitUserEmail=${3:-joy_csharp@yahoo.com}
+ContentTargetGitUserEmail=${3:-joycsc@gmail.com}
ContentSrc=${4:-content}
-ContentTargetGitBranch=${5:-master}
-ContentTargetGitRepoDownloadFolder=${6:-content-repo}
+ContentTargetGitBranch=${5:-content-branch}
+ContentTargetGitRepoDownloadFolder="content-repo"
SOURCE_DIR=$PWD
TEMP_REPO_DIR=$PWD/$ContentTargetGitRepoDownloadFolder
@@ -24,6 +24,11 @@ git rm -r *
echo "Copy documentation into the repo"
cp -r $SOURCE_DIR/$ContentSrc/* .
+echo $PWD
+
+echo "Copy gitignore"
+cp ./../../.gitignore .
+
echo "############################# Setting git identity"
if [ "$2" != "" ]; then
git config user.name $ContentTargetGitUserName