How can I economically scale to 100+ instances of my .Net Core app without using 1 container per instance?

Currently I have a .NET core application, which fires up a new thread to hold each customer account. Each thread instance:

  • Is long running for many months or more
  • Holds open SignalR Websockets and calls 3rd party APIs
  • Needs to be super responsive
  • Has 1 instance for every user account as it connects to unique web sockets / account APIs.

The current plan is to compile this to a Windows Service then deploy 1 application per server instance that uses all resources on the server, then have an orchestrator that manages controlling and deleting the threads through a RabbitMQ integration. We are imagining that 1 server instance could run up to 40 threads or something. Then the orchestrator would create new server instances to manage more accounts as we scale.

I am not happy with this approach as it feels clunky to me. Ideally I’d like to fire up each account instance in it’s own Container using Kubernetes or similar, but the cost of running 1 user account per container is not financially viable.

Are there any other alternatives that anyone can recommend. Other things I’ve been thinking of are to create each account as a separate app as a Windows Service and then fire up multiple versions of the windows service on each server with some kind of service orchestrator.

I am fairly new to architecture like this, so go easy on me if I have not explained this properly. Any advice/ideas on how others could/would approach this would be most appreciated.

Creating generic DAL project in .net

I am looking to create generic DAL project in .net/.net core so it can be used for multiple projects like it will act as template etc.

I am right now aiming to use entity framework to suffice this requirement. Our requirements are as below.

  1. Reading ConnectionString, making connection to DB etc should be already setup. We will make minor changes in config file and it should be ready.
  2. Methods should be generic which will work with all DBs upto extent.
  3. We will create a package of this project and use it in other projects

Though I agree it will differ DB to DB and important part is creation of models per DB, but definitely I am not looking for it.

So, I am looking for the path/guidance to start over it. I have following some below links which uses generic repository pattern(But its way of patters not the project).

Entity Framework Core Generic Repository

https://blog.codingmilitia.com/2019/01/16/aspnet-011-from-zero-to-overkill-data-access-with-entity-framework-core

Any help on this appreciated !

Код ошибки HTTP 403 в .NET Core HttpClient

Пытаюсь отправить http-запрос на мною же только что созданный с помощью ASP .NET Core сервер. Выдаёт либо 403ий код, либо “Система контроля доступа не позволяет выполнить Ваш запрос сейчас, обратитесь к системному администратору…”. Но главное заключается в том, что точно такой же запрос без проблем проходит из браузера, из скрипта на Python и даже из Power Shell. Проблема только в .NET Core! Дальше код запроса:

using System;  using System.Net.Http; using System.Security.Authentication; using System.Net; using System.Threading.Tasks; using System.Diagnostics; using System.IO;  namespace Trying_http_request {     class Program     {          static async Task Main(string[] args)         {             await Request();         }          public static async Task Request()         {             string result = "";             try             {                 HttpClient client = new HttpClient();                 var response = await client.GetAsync("http://localhost:56640/api/values");                 result = await response.Content.ReadAsStringAsync();                  Console.WriteLine(result);             }              catch (WebException ex)             {                 if (ex.Response != null)                 {                     var response = ex.Response;                     var dataStream = response.GetResponseStream();                     var reader = new StreamReader(dataStream);                     var details = reader.ReadToEnd();                     Console.WriteLine("Ошибка:\n" + details);                 }             }         }     } } 

Why all classes in .NET globally inherits from Object class?

Its very interesting for me which advantages gives “global root class” approach for framework. In simple words what reasons resulted the .NET framework was designed to have one root object class with general functionality suitable for all classes.

Nowadays we are designing new framework for internal use (the framework under SAP platform) and we all divided into two camps – first who thinks that framework should have global root, and the second – who thinks opposite.

I am at “global root” camp. And my reasons what such approach would yields good flexibility and development costs reduction cause we will not develop general functionality any more.

So, I’m very interested to know what reasons really push .NET architects to design framework in such way.

Aplicação .net core publicada como sub aplicação no IIS retorna 403 em arquivos js e páginas internas

Possuo uma aplicação .net 4.0 hosteada no IIS www.exemplo.com

Gostaria de implantar uma nova aplicação .net core como sub aplicação da principal ficando www.exemplo.com/novoappcore

Para isso criei uma aplicação e hospedei no IIS.

Implantei a aplicação .net core no IIS como sub aplicação da outra aplicação .net 4.0

Criei um novo application pool para esta nova aplicação.

Instalei o .net core 2.0 no servidor.

A publicação funcionou e consigo acessar a home do meu novo site.

O problema é que ela não carrega o javascript pois retorna 403 Forbiden e também retorna o mesmo erro para outras páginas internas.

Verifiquei que as permissões na pasta estão corretas.

Existe alguma outra configuração que precise ser feita para que a subaplicação funcione corretamente sem retornar 403 ?

.net core publicacion de sitios

net core 2.2.301 en mi linux y ya he desarrollando un aplicación MVC en visual estudio la he subido sin publicar al server y usando el comando dotnet run –urls “http://0.0.0.0:5000” la he puesto a funcionar pero lo que no he logrado es publicarla en visual estudio para después pasarla al servidor y ponerla que se quede permanente esa parte no la he logrado he publicado y visual me ha generado las .dll pero no lo puedo hacer funcionar no se si me puedan ayudar o darme un tutorial de .net core para publicar paginas web usando .net core gracias

Почему написанная мной обертка для COM, работает быстрее чем то что предлагает .NET?

Предыстория была такова, что заметил небольшой интересный факт:

При вызове Marshal.ReleaseComObject(...), освобождается только RCW, а у интерфейсов всегда оставались ссылки и они не освобождались.

Столкнулся с проблемой очень долгого создания объектов COM, используя именно стандартные средства .NET, а если быть точнее, то это интерфейсы помеченные аттрибутами

[ComImport, Guid(...), IntyerfaceType(...)] interface ISomeIUnknownInterface { ... } 

Написанная мной обертка, работает непосредственно с указателем на интерфейс, имеет IUnknown интерфейс, и работает через виртуальную таблицу этого объекта.

Сделал тест скорости создания как минимум главного объекта IDXGIFactory, и при работе со стандартными интерфейсами, объект был получен спустя 2 секунды после вызова, когда возврат указателя на объект занимает порядка 10~100 мс.

Интерфейс и класс выглядят вот так:

[Guid("00000000-0000-0000-C000-000000000046")] public interface IUnknown : IDisposable {     int QueryInterface(in Guid riid, out IntPtr unknownObjectPtr);     uint AddRef();     uint Release(); } 
public class Unknown : IUnknown {     public const uint LastMethodId = 2u;      protected readonly int MethodsCount = typeof(IUnknown).GetMethods().Length;      public Unknown(IntPtr objectPtr)     {         if (IntPtr.Zero == objectPtr)         {             throw new ArgumentException("IUnknown object pointer cannot be IntPtr.Zero or null.",                 nameof(objectPtr));         }          Pointer = objectPtr;         AddMethodsToVTableList(0, MethodsCount);     }      protected IntPtr Pointer { get; set; }      public bool IsDisposed { get; protected set; }      public bool IsValid => Pointer != IntPtr.Zero;      protected List<IntPtr> VirtualTableAddresses { get; private set; } = new List<IntPtr>();      public void Dispose()     {         Dispose(true);         GC.SuppressFinalize(this);     }      public int QueryInterface(in Guid riid, out IntPtr unknownObjectPtr)     {         return GetMethodDelegate<QueryInterfaceDelegate>().Invoke(this, in riid, out unknownObjectPtr);     }      public uint AddRef()     {         return GetMethodDelegate<AddRefDelegate>().Invoke(this);     }      public uint Release()     { #if DEBUG         uint result = #else         return #endif             GetMethodDelegate<ReleaseDelegate>().Invoke(this);  #if DEBUG         Trace.WriteLine($  "{typeof(Unknown).Namespace} — {this}.Release() return value: {result}", "DEBUG"); #endif          return result;     }      protected virtual void Dispose(bool isDisposed)     {         if (IsDisposed || !IsValid)         {             IsDisposed = true;             return;         }          Release();          if (isDisposed)         {             Pointer = IntPtr.Zero;             VirtualTableAddresses.Clear();             VirtualTableAddresses = null;         }          IsDisposed = true;     }      ~Unknown()     {         Dispose(false);     }      protected void AddMethodsToVTableList(int startMethodId, int methodsCount)     {         IntPtr virtualTablePtr = Marshal.ReadIntPtr(this);          for (int i = startMethodId; i < methodsCount + startMethodId; i++)         {             VirtualTableAddresses.Add(Marshal.ReadIntPtr(virtualTablePtr, i * IntPtr.Size));         }     }      protected T GetMethodDelegate<T>() where T : Delegate     {         ComMethodIdAttribute attribute = typeof(T).GetCustomAttribute<ComMethodIdAttribute>();         return Marshal.GetDelegateForFunctionPointer<T>(VirtualTableAddresses[(int) attribute.Id]);     }      public static implicit operator IntPtr(Unknown obj)     {         return obj.Pointer;     }      [ComMethodId(0u), UnmanagedFunctionPointer(CallingConvention.StdCall)]     private delegate int QueryInterfaceDelegate(IntPtr selfPtr, in Guid riid, out IntPtr unknownObjectPtr);      [ComMethodId(1u), UnmanagedFunctionPointer(CallingConvention.StdCall)]     private delegate uint AddRefDelegate(IntPtr selfPtr);      [ComMethodId(2u), UnmanagedFunctionPointer(CallingConvention.StdCall)]     private delegate uint ReleaseDelegate(IntPtr selfPtr); } 

Один из наследованных интерфейсов и объектов:

[Guid("aec22fb8-76f3-4639-9be0-28eb43a67a2e")] public interface IObject : IUnknown {     int SetPrivateData(in Guid name, uint dataSize, byte[] data);     int SetPrivateDataInterface(in Guid name, IUnknown unknown = null);     int GetPrivateData(in Guid name, ref uint dataSize, [In, Out] byte[] data = null);     int GetParent(in Guid riid, out IntPtr parent); } 
public class Object : Unknown, IObject {     protected new const uint LastMethodId = Unknown.LastMethodId + 4u;     protected new readonly int MethodsCount = typeof(IObject).GetMethods().Length;      public Object(IntPtr objectPtr) : base(objectPtr)     {         AddMethodsToVTableList(base.MethodsCount, MethodsCount);         MethodsCount = base.MethodsCount + MethodsCount;     }      public int SetPrivateData(in Guid name, uint dataSize, byte[] data)     {         return GetMethodDelegate<SetPrivateDataDelegate>().Invoke(this, in name, dataSize, data);     }      public int SetPrivateDataInterface(in Guid name, IUnknown iUnknown = null)     {         return GetMethodDelegate<SetPrivateDataInterfaceDelegate>()             .Invoke(this, in name, (Unknown) iUnknown ?? IntPtr.Zero);     }      public int GetPrivateData(in Guid name, ref uint dataSize, [In, Out] byte[] data = null)     {         return GetMethodDelegate<GetPrivateDataDelegate>().Invoke(this, in name, ref dataSize, data);     }      public int GetParent(in Guid riid, out IntPtr parent)     {         return GetMethodDelegate<GetParentDelegate>().Invoke(this, in riid, out parent);     }      [ComMethodId(Unknown.LastMethodId + 1u), UnmanagedFunctionPointer(CallingConvention.StdCall)]     private delegate int SetPrivateDataDelegate(IntPtr thisPtr, in Guid name, uint dataSize, [MarshalAs(UnmanagedType.LPArray)] byte[] data);      [ComMethodId(Unknown.LastMethodId + 2u), UnmanagedFunctionPointer(CallingConvention.StdCall)]     private delegate int SetPrivateDataInterfaceDelegate(IntPtr thisPtr, in Guid name, IntPtr iUnknown);      [ComMethodId(Unknown.LastMethodId + 3u), UnmanagedFunctionPointer(CallingConvention.StdCall)]     private delegate int GetPrivateDataDelegate(IntPtr thisPtr, in Guid name, ref uint dataSize, [In, Out, MarshalAs(UnmanagedType.LPArray)] byte[] data = null);      [ComMethodId(Unknown.LastMethodId + 4u), UnmanagedFunctionPointer(CallingConvention.StdCall)]     private delegate int GetParentDelegate(IntPtr thisPtr, in Guid riid, out IntPtr parent); } 

Такой интерйес и базовый класс, позволяют очень быстро описывать новые объекты, без необходимости дублирования наследуемых методов.

Почему такая реализация быстрее чем стандартные средства работы с COM в .NET?

Subir archivos utilizando VueJS, Axios y .NET CORE

Estoy teniendo problemas con la subida de archivos utilizando axios y ASP.Net Core. No se si el problema esté en mi funcion SubirArchivos del frontend o el problema sea en el controller. Les muestro como esta mi codigo:

Axios

Funcion para realizar la peticion al backend:

SubirArchivos(){                            let formData = new FormData();              for( var i = 0; i < this.files.length; i++ ){             let file = this.files[i];              formData.append('files[' + i + ']', file);             }              axios.post( 'api/Documentos/UploadFiles',             formData,             {                 headers: {                     'Content-Type': 'multipart/form-data'                 }             }             ).then(function(){             console.log('Correcto!');             })             .catch(function(){             console.log('Error!');             });         } 

c#

Esto es en mi controller:

[HttpPost("UploadFiles")]     public async Task<IActionResult> Post(List<IFormFile> files)     {         long size = files.Sum(f => f.Length);          var filePath = Path.GetTempFileName();          foreach (var formFile in files)         {             if (formFile.Length > 0)             {                 using (var stream = new FileStream(filePath, FileMode.Create))                 {                     await formFile.CopyToAsync(stream);                 }             }         }          return Ok(new { count = files.Count, size, filePath });     } 

El problema que tengo pienso yo que es en el backend, pues a la hora de recorrer la lista “files” no contiene ningún archivo.

Estoy haciendo referencia a estos dos links

  • https://serversideup.net/uploading-files-vuejs-axios/
  • https://docs.microsoft.com/en-us/aspnet/core/mvc/models/file-uploads?view=aspnetcore-2.2

¿COMO EXPORTAR UN PROYECTO .NET EN VISUAL ESTUDIO HACIA OTRA SOLUCIÓN?

Tengo una solución en .NET con dos proyectos escritos en C#, en el primer proyecto tengo un programa en desarrollo, en el segundo proyecto tengo una clase con el método y los atributos perfectos para una conexión de consultas con MySQL, ¿De que manera puedo exportar este segundo proyecto a un tipo de archivo .dll o cualquiera que sea el formato adecuado para que posteriormente lo pueda integrar en otras soluciones futuras? y, ¿De que manera se importaría a otra solución?, de manera que no tuviera que escribir nuevamente el código en mis futuras soluciones, únicamente importar este proyecto con la clase que necesito.

Would I have one domain model (.NET Project) for all consumers or one domain model (.NET Project) per consumer?

Say I have a bounded context called: ‘Loans’ and the following APIs:

HSBC NatWest TSB 

The three banks above are consumers and have an API. I am using the scatter gather pattern (https://www.enterpriseintegrationpatterns.com/patterns/messaging/BroadcastAggregate.html).

Would I have one domain model (.NET Project) for all three consumers or one domain model per consumer (.NET Project)? I believe I should have one domain model per consumer as the domain logic is only relevant to that consumer.

This is more of a though experiment rather than a real business problem. However, we will have to do something similar with the scatter gather pattern at some point so hence the question.

I realise both approaches I have described will work. I am talking more from the perspective pf the principle of least astonishment.