Can I run two TestServers on one environment, with different configs? - c#

I am writing a process that brokers data transfer between two identical APIs (FWIW, one is a local API running in a different container, and the other is in the cloud).
I want to write some test code to ensure that the data transfer code does what it should. Up till now, I've been using TestServer for API tests, but now things might get a little complicated when I want to run two servers. A couple of questions arise:
How do I get them to use different appsettings.json files? Right now, with just one TestServer, it's using the appsettings.json of the test project. How do you configure a TestServer to use a different config file?
Once I have two TestServers up and running, do they function as completely independent entities? Most particularly, if I have any static values, will their values be shared between the two environments, or can they function independently, as they would in real life?

This depends a little bit on how you're creating your TestServer.
If you're using TestServer's constructor (which takes a IWebHostBuilder as input), you can use the web host builder's ConfigureAppConfiguration method to setup whatever configuration sources you want. Appsettings.json is the default config source if you don't change anything, but it should be easy to create two separate TestServers using different IWebHostBuilders, each with their own ConfigureAppConfiguration call.
If you're using the WebApplicationFactory approach, you can create a custom WebApplicationFactory and setup configuration sources in that type's ConfigureWebHost method.
Since they run in the same process/appdomain, the two TestServers will be separate instances but share statics. If that's not desirable, you could consider running on of the servers out-of-process as a 'real' server (instead of a TestServer) or, maybe even better, avoid the use of statics!

We need a lot more information here... How are you registering your appsettings.json? Are you using DI?
a) Transform your config for your environment (server/cloud)
How do I transform appsettings.json in a .NET Core MVC project?
b) Create a second appsettings and change that in your application config.
https://learn.microsoft.com/en-us/aspnet/core/fundamentals/configuration/?view=aspnetcore-2.2

Related

ASP.NET Core pipelines from within the same main application

Is it possible to run parallel ASP.NET Core pipelines from within the same main application. I want to expose an endpoint for external consumers and would like to register only few services for that endpoint when compared to main application. Is there any way to properly do it in asp.net core?
I could see a similar implementation here and it is almost 2 yrs old. Is there a better way to do it? Or is it the only way right now?
https://www.strathweb.com/2017/04/running-multiple-independent-asp-net-core-pipelines-side-by-side-in-the-same-application/
So, what problem in this solution? You can use Map, MapWhen, UseBranchWithServices. It's good solution.
One more point is to try create two hosts in main. But I not realy enshure that it can be implemented.
One another solution, you can create independent app and setup nginx (iis) in the front of 2 instances. Then you get the independent pipeline, independent configuration, you can deploy it to different machines and so on.
But when you change the code you should redeploy 2 applications in the same time.
So, you should answer on question: is it should be independent part of system, you you want to some small specific configuration for this API.
If you need first variant please use another instance, if second - use MapWhen, UseBranchWithServices and so one.

log4 net multiple loggers vs single logger in an application?

We have c# application with several different modules. We are using log4net for logging. What should be done to log the messages:
Create a centralized logging project: The application classes to use centralized logging project's dll's static methods to log the messages. So, no class in application creates the logger, all logging requirements to be fulfilled by this dll OR
All types in the application itself creating their own loggers: Easy to check which type generates which message, easy to manage different type of logging requirements i.e.we can throttle logging behavior of each type independently, like one class logging ALL logs but other only loggin ERROR.
What is the preferred practise?
The approach2 has its own benefit but approach1 looks clean as each class would no longer be responsible for calling "GetLogger(typeOf(className))".
What is the recommended way?
It really depends on the usecase, when making a library it can make sense to use method 1. However when making a complex program method 2 will help you to manage different logger independently. Method 2 will give the also the option to log all in you project like method 1 does. However method 1 does not support differing on logger. So method 2 seems a better choice in most cases.

Creating an Interaction Test Class c# that takes in files from web.config

So I am trying to test a web service written in .NET framework 4.0 and c#. I am fairly new to the language and framework and language in general. My problem is that I want to create a test class for a service that takes an object from mongodb edits it then replaces it. I want to test the retrieval, editing, and saving of this object. The variables required for setting up server, db, and collection in the actual service are stored in web.config. I know I should use app.config for the test to load the relevant variables. My thought process for how to test this is to have two local mongodb databases: one that I load the objects off of and then persist them back and one that is clean for comparison st. Assert.NotEqual(changedDBObject, cleanDBObject) works.
Design wise is this a bad way of building this test? I could use some direction on the correct way to setup app.config preferably in a way that I can still use the same class that I use to read web.config. The main goal is to write a test class that does not require me to rework the original code beyond recognition just to use the test class and still be able to have a modular, reusable, fast running etc. test class.

How to configure AutoMapper if not ASP.net Application?

I'm using AutoMapper in a number of projects within my solution.
These projects may be deployed independantly, across multiple servers.
In the documentation for AutoMapper it says:
If you're using the static Mapper
method, configuration only needs to
happen once per AppDomain. That means
the best place to put the
configuration code is in application
startup, such as the Global.asax file
for ASP.NET applications.
Whilst some of the projects will be ASP.net - most of these are class libraries / windows services.
Where should I be configuring my mappings in this case?
The idea that it should only be required once per AppDomain stays the same, as far as I can tell. I always perform my mappings upon the initialization of the program itself. While I am not using AutoMapper I am using an IoC library (Windsor) which requires a mapping of sorts and this is done from my program.cs file. So when the application loads it performs the mapping and because the resolver is static and in a shared library it is available globally.
I don't know if this answers your question or not, but essentially every app has an entry point and if you need your mappings immediately after entry then the entry is the best place to put them.
I've elected to store my mappings in separate classes for each project so that they are reusable.
protected void Application_Start()
{
RegisterMaps();
}
private void RegisterMaps()
{
WebAutoMapperSettings.Register();
BusinessLogicAutoMapperSettings.Register();
}
This way I can easily call BusinessLogicAutoMapperSettings.Register() if I were to reuse only my BusinessLogic dll in another application or webservice

C# Web Service and using a variable

I need to create a project for multiple web services using WCF in c#. The web services will be calling other assemblies to perform the core processing. The assemblies will be accessing data from SQL Server. One of the parameters that will be part of every web service method will include the database to use. My problem is how to pass the database parameter to assemblies to use. I can't change all the signatures for all the satellite assemblies to use. I want to reference some kind of variable that the satellite assembles reference. Theses same satellite assemblies are used with a Windows Forms app and an ASP.NET app so I would need to have something that all types of applications could use. Static fields are not good since for one web service call the database could be "X" and for another it would be "Y". Any ideas?
This is the sort of thing that might play nicely with an IoC or DI framework - having some interface that includes the database information, and have it pushed into all the callers for you. Even without IoC, hiding the implementation in an interface sounds like a solid plan.
With your static concept; a [ThreadStatic] might work but is a little hacky (and you need to be religious about cleaning the data between callers), or another option is to squirrel some information away on the Principal, as this is relatively easily configured from both WCF (per-call) and winforms (typically per-process). In either case, be careful about any thread-switching (async, etc). In particular, note that ASP.NET can change threads in the middle of a single page pipeline.

Categories