McpNetwork.MicroServiceCore 7.0.1

dotnet add package McpNetwork.MicroServiceCore --version 7.0.1
NuGet\Install-Package McpNetwork.MicroServiceCore -Version 7.0.1
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="McpNetwork.MicroServiceCore" Version="7.0.1" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add McpNetwork.MicroServiceCore --version 7.0.1
#r "nuget: McpNetwork.MicroServiceCore, 7.0.1"
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install McpNetwork.MicroServiceCore as a Cake Addin
#addin nuget:?package=McpNetwork.MicroServiceCore&version=7.0.1

// Install McpNetwork.MicroServiceCore as a Cake Tool
#tool nuget:?package=McpNetwork.MicroServiceCore&version=7.0.1

McpNetwork.MicroServiceCore

Core implementation for micro-services.

MicroServiceCore permits to easilly implement a micro-service, including Dependency Injection ,API Gateway, WebSocket, Authorization control and Razor pages. Based

Getting started :

Create a new solution including files listed herebelow.

Create your tree structure as indicated in appSettings.xml file.

Open a browser and navigate to http://localhost:7777/swagger/.

MicroServiceCore also provides some statistics pages (http://localhost:7777/api/0.0/service/statistics).

File Program.cs

using System;

namespace DemoService
{
	class Program
	{
		static void Main(string[] args)
		{
			var host = new DemoServiceHost();
			host.Start();

			var exit = false;
			while (!exit)
			{
				Console.WriteLine("Server started. Press [Q] to quit.");
				var input = Console.ReadKey(false);
				exit = input.Key == ConsoleKey.Q;
			}
			host.Stop();

		}
	}
}

File DemoServiceHost.cs

using DemoService.Dependencies;
using log4net;
using McpNetwork.MicroServiceCore.Models;
using McpNetwork.MicroServiceCore.Models.Enums;
using McpNetwork.MicroServiceCore.WebHost;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Reflection;

namespace DemoService
{
    /// <summary>
    /// This is the Demo micro-service.
    /// </summary>
    class DemoServiceHost : AWebHost
    {

        // Logger
        private static ILog SystemLogger => LogManager.GetLogger(typeof(DemoServiceHost));

        // Stores list of available authentication tokens
        internal readonly static List<string> AvailableTokens = new List<string>();

        // microservice name
        public override string ServiceName => "DemoService";
        // microservice description
        public override string ServiceDescription => "Service for demonstration";

    
        /// <summary>
        /// .ctor
        /// </summary>
        public DemoServiceHost()
        {
        
            // setup Log4Net
            this.SetupLog4Net();


            // Api Gateway handler
            this.GetApiRoute = this.GetApiRouteAction;
            // Authentication token validation handler
            this.ValidateToken = this.ValidateTokenAction;
            // microservice shutdown handler
            this.OnServiceStopping = this.RegisterShutDown;
            // microservice startup handler
            this.OnServiceStarted = this.RegisterStartUp;

            #region external microservice
                        // The following code loads an external dll as part of this micro-service (code not shown here)
            var binPath = new FileInfo(Assembly.GetExecutingAssembly().Location).Directory.FullName;
            var assemblyPath = Path.Combine(binPath, "ExternalService.dll");
            var assembly = Assembly.LoadFrom(assemblyPath);
            this.AddAssemblyControllers(assembly);
            #endregion

            // Application model convention
            this.ApplicationModelConvention = new ApplicationModelConvention();

            // Add extra dependencies to controllers
            this.AddDependencies(
                new List<DependencyModel>
                {
                    new DependencyModel
                    {
                        ServiceLifetime = ServiceLifetime.Scoped,
                        Type = typeof(IScopedDependency),
                        Implementation = typeof(DependencyClass),
                    },
                    new DependencyModel
                    {
                        ServiceLifetime = ServiceLifetime.Transient,
                        Type = typeof(ITransientDependency),
                        Implementation = typeof(DependencyClass),
                    },
                    new DependencyModel
                    {
                        ServiceLifetime = ServiceLifetime.Singleton,
                        Type = typeof(ISingletonDependency),
                        Implementation = new DependencyClass(),
                    }
                });
        }

        /// <summary>
        /// Authentication token validation handler
        /// </summary>
        /// <param name="token"></param>
        /// <param name="authorizationRole"></param>
        /// <returns></returns>
        private ECheckTokenResult ValidateTokenAction(string token, string authorizationRole)
        {
            return DemoServiceHost.AvailableTokens.Contains(token) ? ECheckTokenResult.Allowed : ECheckTokenResult.Disabled;
        }

        /// <summary>
        /// Api gateway handler (act as a proxy server)
        /// </summary>
        /// <param name="request"></param>
        /// <returns>null if no redirection, new Uri otherwise</returns>
        private Uri GetApiRouteAction(HttpRequest request)
        {
            var pathParts = request.Path.ToString().Split('/');
            // according to application model convention : 
            //  pathParts[0] -> /
            //  pathParts[1] -> api
            //  pathParts[2] -> <version>
            //  pathParts[3] -> <controller>
            //  pathParts[4] -> <action>

            if (pathParts.Length < 3 )
            {
                return null;
            }

            switch (pathParts[3])
            {
                case "Demo":
                    switch (pathParts[4])
                    {
                        case "SourceRequest":
                            var newUrl = String.Format("{0}://{1}/api/{2}/{3}/DestinationRequest", request.Scheme, request.Host.Value, pathParts[2], pathParts[3]);
                            return new Uri(newUrl);
                    }
                    break;
            }
            return null;
        }

        private void RegisterShutDown()
        {
            Console.WriteLine("Service is now stopping...");
        }
        private void RegisterStartUp()
        {
            Console.WriteLine("Service is now started...");
        }

        #region Settings

        /// <summary>
        /// Get settings (required by AWebHost)
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <returns></returns>
        public override T GetSetting<T>(string key)
        {
            return GetSetting<T>(key, default, true);
        }

        /// <summary>
        /// Get settings (required by AWebHost)
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <param name="defaultValue"></param>
        /// <returns></returns>
        public override T GetSetting<T>(string key, T defaultValue)
        {
            return GetSetting<T>(key, defaultValue, false);
        }

        /// <summary>
        /// Get connection string (required by AWebHost)
        /// </summary>
        /// <param name="connectionStringName"></param>
        /// <returns></returns>
        public override string GetConnectionString(string connectionStringName)
        {
            return ConfigurationManager.ConnectionStrings[connectionStringName].ConnectionString;
        }

        private T GetSetting<T>(string key, T defaultValue, bool throwOnSettingNotSet)
        {
            T fctResult = defaultValue;
            if (!ConfigurationManager.AppSettings.AllKeys.ToList().Contains(key) && throwOnSettingNotSet)
            {
                var message = String.Format("Setting [{0}] is not set in configuration file", key);
                SystemLogger.Fatal(message);
                throw new Exception(message);
            }

            Type t = Nullable.GetUnderlyingType(typeof(T)) ?? typeof(T);
            object value = ConfigurationManager.AppSettings[key] ?? null;
            switch(t.BaseType.Name)
            {
                case "Enum":
                    fctResult = (T)Enum.Parse(typeof(T), value.ToString());
                    break;
                default:
                    fctResult = value == null ? fctResult : (T)Convert.ChangeType(value, t);
                    break;
            }
            return fctResult;

        }
#endregion

#region Log4Net
        private void SetupLog4Net()
        {
            var log4netConfig = this.GetSetting<string>("Service.Log4Net.ConfigurationFile");
            var log4netInfo = new FileInfo(log4netConfig);
            var logRepository = LogManager.GetRepository(Assembly.GetEntryAssembly());
            log4net.Config.XmlConfigurator.ConfigureAndWatch(logRepository, log4netInfo);
        }

#endregion

#region Logs
        protected override void LoggerDebugFired(object sender, ServiceLogModel arg) { SystemLogger.Debug(arg); }
        protected override void LoggerErrorFired(object sender, ServiceLogModel arg) { SystemLogger.Debug(arg); }
        protected override void LoggerFatalFired(object sender, ServiceLogModel arg) { SystemLogger.Debug(arg); }
        protected override void LoggerWarningFired(object sender, ServiceLogModel arg) { SystemLogger.Debug(arg); }
        protected override void LoggerInfoFired(object sender, ServiceLogModel arg) { SystemLogger.Debug(arg); }

#endregion

    }
}

AppSettings.xml

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <connectionStrings>
	<add name="MicroServiceEntities" connectionString="D:\Dev\MicroServiceCore\wwwFiles\Database\demoService.db"/>
  </connectionStrings>
  <appSettings>

	
	<add key="RestApi.Timeout.Seconds" value="10" />

    <add key="Service.WebServer.SecuredPort" value="433" />
    <add key="Service.WebServer.UnSecuredPort" value="7777" />
    <add key="Service.WebServer.CertificateName" value="DemoServiceCertificate.pfx" />
    <add key="Service.WebServer.CertificatePassword" value="DemoServicePassword" />
    <add key="Service.WebServer.CertificateLocation" value="FromFile" />
    <add key="Service.WebServer.AcceptSelfSignedCertificates" value="true"/>
	<add key="Service.WebServer.DisableChunkedResponse" value="false" />
	  
	<add key="Service.Token.HeaderName" value="X-DemoServiceToken" />

	

	
	<add key="Service.WwwRoot.Folder" value="D:\Dev\MicroServiceCore\wwwFiles\wwwRoot" />
	<add key="Service.Views.Folder" value="D:\Dev\MicroServiceCore\wwwFiles\Views" />
	<add key="Service.Log4Net.ConfigurationFile" value="D:\Dev\MicroServiceCore\wwwFiles\log4net.Service.config" />

  </appSettings>

</configuration>

File ApplicationModelConvention.cs

using Microsoft.AspNetCore.Mvc.ApplicationModels;
using System.Linq;

namespace DemoService
{
	public class ApplicationModelConvention : IApplicationModelConvention
	{
		public void Apply(ApplicationModel application)
		{
			var centralPrefix = new AttributeRouteModel(new AttributeRouteModel() { Template = "api/{version}" });
			foreach (var controller in application.Controllers)
			{
				var routeSelector = controller.Selectors.FirstOrDefault(x => x.AttributeRouteModel != null);
				if (routeSelector != null)
				{
					routeSelector.AttributeRouteModel = AttributeRouteModel.CombineAttributeRouteModel(centralPrefix, routeSelector.AttributeRouteModel);
				}
				else
				{
					controller.Selectors.Add(new SelectorModel() { AttributeRouteModel = centralPrefix });
				}
			}
		}
	}
}

File IDependencies.cs

using System;

namespace DemoService.Dependencies
{
	public interface ISingletonDependency
	{
		Guid GetGuid();
	}
	public interface IScopedDependency
	{
		Guid GetGuid();
	}
	public interface ITransientDependency
	{
		Guid GetGuid();
	}
}

File DependencyClass.cs

using System;

namespace DemoService.Dependencies
{
	public class DependencyClass : ISingletonDependency, IScopedDependency, ITransientDependency
	{
		private readonly Guid Guid = Guid.NewGuid();
		public Guid GetGuid()
		{
			return this.Guid;
		}
	}
}

File DemoController.cs

using DemoService.Dependencies;
using McpNetwork.MicroServiceCore.Models.Attributes;
using McpNetwork.MicroServiceCore.Tools.Controllers;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.StaticFiles;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.IO;
using System.Reflection;

namespace DemoService.Controllers
{
    [Route("[controller]")]
    [ApiController]
    public class DemoController : AServiceController
    {

        private readonly IScopedDependency scopedDependency;
        private readonly ITransientDependency transientDependency;
        private readonly ISingletonDependency singletonDependency;

        public DemoController(IServiceProvider serviceProvider) : base(serviceProvider) 
        {
            scopedDependency = serviceProvider.GetService<IScopedDependency>();
            transientDependency = serviceProvider.GetService<ITransientDependency>();
            singletonDependency = serviceProvider.GetService<ISingletonDependency>();
        }

        [HttpGet("[action]"), Produces("text/plain")]
        [MicroService(true)]
        public string Ping()
        {
            this.ServiceLogger.Info("Executing ping request");
            this.ServiceLogger.Debug(String.Format("Scoped Guid : {0}", scopedDependency.GetGuid().ToString()));
            this.ServiceLogger.Debug(String.Format("Transient Guid : {0}", transientDependency.GetGuid().ToString()));
            this.ServiceLogger.Debug(String.Format("Singleton Guid : {0}", singletonDependency.GetGuid().ToString()));
            return "OK";
        }

        [HttpGet("[action]")]
        [MicroService(true)]
        public string GetToken()
        {
            var result = Guid.NewGuid().ToString();
            DemoServiceHost.AvailableTokens.Add(result);
            return result;
        }

        [HttpGet("[action]")]
        [MicroService(false)]
        public string NeedAuthentication()
        {
            return ("Gotcha");
        }

        [HttpGet("[action]"), Produces("application/octet-stream")]
        [MicroService(true)]
        public ActionResult DownloadFile()
        {
            var assemblyLocation = new FileInfo(Assembly.GetExecutingAssembly().Location);
            var fileName = Path.Combine(assemblyLocation.Directory.FullName, "Files/README.zip");

            var provider = new FileExtensionContentTypeProvider();
            if (!provider.TryGetContentType(fileName, out var contentType))
            {
                contentType = "application/octet-stream";
            }

            var bytes = System.IO.File.ReadAllBytesAsync(fileName).Result;
            return File(bytes, contentType, Path.GetFileName(fileName));

        }

        #region Api Gateway purpose

        [HttpGet("[action]"), Produces("text/plain")]
        [MicroService(true)]
        public string SourceRequest()
        {
            // SourceRequest API is redirected to DesctinationRequest via Api Gateway 
            // (see DemoServiceHost.GetApiRouteAction method)
            throw new Exception("You should not arrived here !");
        }

        [HttpGet("[action]"), Produces("text/plain")]
        [MicroService(true)]
        public string DestinationRequest()
        {
            return "Coming from DestinationRequest endpoint";
        }

        #endregion

    }
}
Product Compatible and additional computed target framework versions.
.NET net7.0 is compatible.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
7.0.1 167 6/13/2023
7.0.0 326 11/14/2022
6.3.0 380 10/13/2022
6.2.0 370 3/20/2022