McpNetwork.MicroServiceCore
7.0.1
dotnet add package McpNetwork.MicroServiceCore --version 7.0.1
NuGet\Install-Package McpNetwork.MicroServiceCore -Version 7.0.1
<PackageReference Include="McpNetwork.MicroServiceCore" Version="7.0.1" />
paket add McpNetwork.MicroServiceCore --version 7.0.1
#r "nuget: McpNetwork.MicroServiceCore, 7.0.1"
// 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 | Versions 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. |
-
net7.0
- FluentValidation (>= 11.5.2)
- McpNetwork.SystemMetrics (>= 7.0.0)
- Microsoft.AspNetCore.Mvc.NewtonsoftJson (>= 7.0.7)
- Microsoft.EntityFrameworkCore (>= 7.0.7)
- Microsoft.EntityFrameworkCore.Sqlite (>= 7.0.7)
- Microsoft.Extensions.Hosting (>= 7.0.1)
- Microsoft.Extensions.Hosting.Abstractions (>= 7.0.0)
- Newtonsoft.Json (>= 13.0.3)
- RazorEngine.NetCore (>= 3.1.0)
- Swashbuckle.AspNetCore.Swagger (>= 6.5.0)
- Swashbuckle.AspNetCore.SwaggerGen (>= 6.5.0)
- Swashbuckle.AspNetCore.SwaggerUI (>= 6.5.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.