Do these static application properties need to be locked? - c#

In my web application, I read some settings from an external config file during Application_Start, then access them across the application's many methods:
namespace Common
{
public static class CommonConfigSettings
{
public static string DataSource { get; set; }
public static string DatabaseName { get; set; }
public static string DatabaseUserName { get; set; }
public static string DatabasePassword { get; set; }
}
}
During Application_Start these are read from an XML file into the static variable:
DataSource = els.FirstOrDefault(item => item.Attribute("key").Value == "DataSource").Attribute("value").Value;
DatabaseName = els.FirstOrDefault(item => item.Attribute("key").Value == "DatabaseName").Attribute("value").Value;
DatabaseUserName = els.FirstOrDefault(item => item.Attribute("key").Value == "DatabaseUserName").Attribute("value").Value;
DatabasePassword = els.FirstOrDefault(item => item.Attribute("key").Value == "DatabasePassword").Attribute("value").Value;
In the application they are used as follows:
myConn.ConnectionString = string.Format("Persist Security Info=False; User ID={0}; Password={1}; Initial Catalog={2}; Data Source={3}; Connection Timeout=60",
CommonConfigSettings.DatabaseUserName,
CommonConfigSettings.DatabasePassword,
CommonConfigSettings.DatabaseName,
CommonConfigSettings.DataSource);
At no point in time are the static values written to following Application_Start - they are only read back out (although perhaps by 2+ people simultaneously). There are also no static methods, just properties. I read about locking and thread safety here and here, but have only confused myself. Should I implement locking on these values, and if so, at what point please?

If you are absolutely sure that those properties are written just once (and prior to all read operations), there is no need for locking.
EDIT: The question is: Will it always be so? If you would come to the need to replace this database access information at runtime, you would run into the problem of non-atomic operations (e.g. reading a new database username and and old password if the writing thread would be interrupted at the right/"wrong" time). May be it would be good to provide a method to return all needed data in a single struct. This method can be provided with a thread locking mechanism in the future if the need would arise...
public struct DatabaseAccessData
{
public string DataSource { get; set; }
public string DatabaseName { get; set; }
public string DatabaseUserName { get; set; }
public string DatabasePassword { get; set; }
}
public static class CommonConfigSettings
{
private static string DataSource { get; set; }
private static string DatabaseName { get; set; }
private static string DatabaseUserName { get; set; }
private static string DatabasePassword { get; set; }
public static void SetDatabaseAccessData(DatabaseAccessData data)
{
DataSource = data.DataSource;
DatabaseName = data.DatabaseName;
DatabaseUserName = data.DatabaseUserName;
DatabasePassword = data.DatabasePassword;
}
public static DatabaseAccessData GetDatabaseAccessData()
{
return new DatabaseAccessData
{
DataSource = DataSource,
DatabaseName = DatabaseName,
DatabaseUserName = DatabaseUserName,
DatabasePassword = DatabasePassword
};
}
Let me say that i am not a fan of "static" in this case. If some of your classes depend on having the common configuration settings, you should pass an instance of CommonConfigSettings to them via constructor parameter or property (see "Dependency injection"). I prefer the first, as it is more rigid / strict; you cannot forget to pass an important dependency then.

Related

Correct way to initialize settings in .net core 2.2?

I created an REST api application which has many settings and stored in database. These settings are used during filtering and inserting data to the table.
Because I need to access settings every time I need to insert data. Instead of accessing settings from database, I created a global settings class and I put every settings in that class.
public static class GlobalSettings
{
public static string Setting_1;
public static string Setting_2;
public static string Setting_3;
public static string Setting_4;
public static void Initialize(ISettingsRepo repo)
{
try
{
var settings = new GSettings(repo);
Setting_1 = settings.SetSetting_1();
Setting_2 = settings.SetSetting_2();
Setting_3 = settings.SetSetting_3();
Setting_4 = settings.SetSetting_4();
}
catch (Exception ex)
{
throw new Exception("Error when loading settings.\r\n" + ex.Message);
}
}
}
Here ISettingsRepo is scoped service that will load the settings from database. The functions will initialize the settings to the properties.
Now to initialize GlobalSettings I used configure method in startup class like this.
using (var scope = app.ApplicationServices.CreateScope())
{
Settings.GlobalSettings.Initialize(scope.ServiceProvider
.GetRequiredService<Data_Repo.Settings.ISettingsRepo>());
}
Now I can use this in controller or anywhere in my api and get settings without accessing database. Also I can reload the GlobalSettings any time if settings are updated. But does this method correct way or has memory leak problems?
Is there any better method to do this.?
Example
My appsetting.json have structure like this.
"EmailSettings": {
"MailServer": "",
"MailPort": ,
"Email": "",
"Password": "",
"SenderName": "",
"Sender": "",
"SysAdminEmail": ""
},
I will define my class like this
public class EmailSettings
{
public string MailServer { get; set; }
public int MailPort { get; set; }
public string SenderName { get; set; }
public string Sender { get; set; }
public string Email { get; set; }
public string Password { get; set; }
public string SysAdminEmail { get; set; }
}
So we have the the config structure. The last thing we need is register inside Startup.cs
services.Configure<EmailSettings>(configuration.GetSection("EmailSettings"));
To use it inside service class
private readonly IOptions<EmailSettings> _emailSetting;
public EmailSender(IOptions<EmailSettings> emailSetting)
{
_emailSetting = emailSetting;
}
email.From.Add(new MailboxAddress(_emailSetting.Value.SenderName, _emailSetting.Value.Sender));

C# - Read json to subclass fields

I'm trying to make a Config.cs class to use on my project.
Structure is supposed to consist of categories of settings. For example, Config.LogOnDetails should hold the values for MySQL login.
Here is my current structure.
public class Config
{
public string pPath;
public string configPath;
public string configFilePath;
public class LogOnDetails
{
public string MySQLDatabaseName { get; set; }
public string MySQLUser { get; set; }
public string MySQLPassword { get; set; }
public string MySQLAddress { get; set; }
}
public Config()
{
pPath = Directory.GetCurrentDirectory();
configPath = Path.Combine(pPath, #"/config");
configFilePath = Path.Combine(configPath, "/config.json");
//If it doesn't exist, create a directory for the configuration to be stored in
if (!Directory.Exists(configPath))
{
Directory.CreateDirectory("config");
}
if (!File.Exists(configFilePath))
{
string json = JsonConvert.SerializeObject(this);
File.WriteAllText(configFilePath, json);
Console.WriteLine("Created a new blank config file!");
}
}
}
Here is how I'm trying to load the config to the class.
//Initialize configuration
Config.LogOnDetails logOnDetails = new Config.LogOnDetails();
//Load config from json
config.LogOnDetails = JsonConvert.DeserializeObject<Config.LogOnDetails>(config.configFilePath);
But this doesn't seem to work and looks like I don't understand subclasses properly. How can I organize my class so it will work?
json example:
{
"pPath": null,
"configPath": null,
"configFilePath": null,
"MySQLDatabaseName": null,
"MySQLUser": null,
"MySQLPassword": null,
"MySQLAddress": null
}
First off, I'm going to start with a general point. The Config class should know nothing about how it is stored, or where it is stored. That is a completely separate "concern". See Separation of concerns
Start off with the definition of what you want to store. That seems to be your MySql info, and some other info. These should all be individual classes (To be clear, you can nest them, but there is no need to and complicates the answer a little):
public class LogOnDetails
{
public string MySQLDatabaseName { get; set; }
public string MySQLUser { get; set; }
public string MySQLPassword { get; set; }
public string MySQLAddress { get; set; }
}
You can have another one:
public class Settings
{
public string Locale { get; set; }
}
And you can compose these into a master config object
public class Config
{
public string SomeTopLevelProp {get; set; }
public LogOnDetails LogOnDetails { get; set; }
public Settings Settings { get; set; }
}
The way to serialize and deserialize this is fairly straightforward
var config = new Config()
{
SomeTopLevelProp = "ABCDEF",
LogOnDetails = new LogOnDetails()
{
MySqlDatabaseName = "Foo" ,
MySQLUser = "MyUser"
// snip the rest of the props
},
Settings = new Settings
{
Locale = "en-GB"
}
}
var json = JsonConvert.SerializeObject(config );
var mySettingDeserialized = JsonConvert.DeserializeObject<Config>(json);
I have purposely left out the writing to a file part - you seem to know how to do that - but keep it outside of the Config class. For example a separate classes, perhaps just with 2 static methods which knows how/where to store the config
public static class ConfigLoader
{
public static void StoreConfig(Config config, string location) {... }
public static Config LoadConfig(string location) {... }
}
A note on security - storing your database password as plain text in a json config file is generally a bad idea. You might consider encrypting it, and storing that and decrypting it when using the value.

How to return specific set of data from a class

I have a similar structure to the one below
Base class
public class BaseClass
{
public string Name { get; set; }
public string Address { get; set; }
public int Age { get; set; }
public Guid Guid { get; set; }
public string Hometown { get; set; }
}
Derived Class
public class DerivedClass : BaseClass
{
public List<DerivedClassDataItem> Data { get; set; }
}
Data class
public class DerivedClassDataItem
{
public string Datum1 { get; set; }
public string Datum2 { get; set; }
public string Datum3 { get; set; }
public string Datum4 { get; set; }
public int Datum5 { get; set; }
public DateTime Datum6 { get; set; }
}
What is the best practice to return specific set of info from the DerivedClass?
a potential set could be:
Name, Address, Guid and then a Data list that only contains Datum1 and Datum4
I could see anonymousTypes, Tuples or another set of class(es), all to be valid approaches.
My concern about creating new set of classs for the set returned is that the class(s) structure will be similar to the structure of the three mentioned above except it will have fewer selected members, which to me, does not sound ideal. (duplicate code and structure)
Using anonymousTypes was my initial solution to tackle this, something like
List<DerivedClass> list = new List<DerivedClass>();
var mySet = list.Select(d => new
{
Name = d.Name,
Address = d.Address,
.
.
.
.
.
Data = d.Data.Select(item => new
{
Datum1 = item.Datum1,
Datum4 = item.Datum4
})
});
but again, that was a headache for us to track through httpResponse and through out API calls.
Should I go with Tuple?
Any insights as to what is the best practice for doing this?
Edit
I am using this set of data to be a response returned by a API/GET call. I will send the set back using HttpRespose and then the framework will transform that into json
this is an actual method we have now
private void populateReturnFile()
{
var returnFileAnonymous = new
{
Vendor = this.Vendor,
OrganizationName = this.OrganizationName,
User = this.User,
Platform = this.Platform,
DictionaryType = this.DictionaryType,
UseCaseId = this.UseCaseId,
Data = this.Data.Select(d => new
{
MigrationTermId = d.MigrationTermId,
ImoLexicalCode = d.ImoLexicalCode
})
};
this.returnFile = returnFileAnonymous;
}
Then my GET will return the retunFile (this is a very simple method, i have remove irrelevant code)
[HttpGet]
public HttpResponseMessage Get(Guid migrationFileId)
{
ProblemList problemList = ProblemList.GetProblemList(migrationFileId);
return Request.CreateResponse(HttpStatusCode.OK, problemList.ReturnFile, new JsonMediaTypeFormatter());
}
If API calls is where you are using these classes, then I personally like to keep it simple and avoid complex inheritance hierarchy. Remember, simple code is good code.
I would make a separate class for each api request/response call. For very simple api calls (ajax requests for example) I like to use anonymous types, but for controllers that only handle API calls I like to create separate classes, organized in a nice folder structure.
Everyone has their "style" but as long as you strive for simplicity your code will be maintainable.

Writing a concise string storage pattern

I have a series of classes used to represent identifiers in my project that are supposed to have a specific string storage format. I don't have control on this format.
The classes are pure containers, they don't do anything. The storage format is of the form "CLASSSTYPE|key1|key2|key3|...|keyN". Each "key" can be mapped to one property of the class.
Right now the FromStorageString and ToStorageString functions look like this:
public class SomeTypeId : IObjectId
{
public static string ToStorageString(SomeTypeId id)
{
return string.Format("{0}|{1}|{2}", typeof(SomeTypeId).Name, MyIntKey, MyStringKey);
}
public static SomeTypeId FromStorageString(IdReader source)
{
int intKey = source.Retrieve<int>();
string stringKey = source.Retrieve<string>();
return new SomeTypeId(intKey, stringKey);
}
public int MyIntKey { get; private set; }
public string MyStringKey { get; private set; }
public SomeTypeId(int intKey, string stringKey)
{
MyIntKey = intKey;
MyStringKey = stringKey;
}
}
We are checking the From/To consistency in unit tests, but I feel there should be a way to simplify the set up and perform the check a compile-time.
What I had in mind is something like this:
[Storage("MyIntKey", "MyStringKey")]
public class SomeTypeId : IObjectId
{
private SomeTypeId() {}
public int MyIntKey { get; private set; }
public string MyStringKey { get; private set; }
public SomeTypeId(int intKey, string stringKey)
{
MyIntKey = intKey;
MyStringKey = stringKey;
}
}
But first I don't know how to do this with the no parameters constructor and the property setters staying private. I am reluctant to have them public.
Second this approach is not robust to property name change and typos because the property names in the attribute are strings.
Should I expose the setters and private constructor ?
Is there a better way of doing this ?

MongoDb C# driver: mapping events to read database in cqrs solution

We're using MongoDb as a datasource for our application, which is built using cqrs and event sourcing. The problem that we faced today is what is the best way to implement mapping (denormalization) of events to read database. For example, we have a user MongoDb collection which contains all info about user.We have event like this:
[Serializable]
public class PasswordChangedEvent : DomainEvent
{
private string _hashedPassword;
private string _salt;
public PasswordChangedEvent()
{
}
public PasswordChangedEvent(string hashedPassword, string salt, DateTime createdDate)
:base(createdDate)
{
HashedPassword = hashedPassword;
Salt = salt;
}
public string HashedPassword
{
private set { _hashedPassword = value; }
get { return _hashedPassword; }
}
public string Salt
{
private set { _salt = value; }
get { return _salt; }
}
}
And read DTO like
public class User : BaseReportDataObject
{
public string Name { get; set; }
public string Email { get; set; }
public string Gender { get; set; }
public DateTime? BirthDate { get; set; }
public string HashedPassword { get; set; }
public string Salt { get; set; }
public string RestoreHash { get; set; }
public string OpenIdIdentifyer { get; set; }
}
Our current solution for updating documents with events goes like this: we have some mapping code for our events (BsonClassMap.RegisterClassMap etc.) and code for update:
MongoCollection.Update(Query<PasswordChangedEvent>.EQ(ev => ev.AggregateId, evnt.AggregateId),
Update<PasswordChangedEvent>
.Set(ev => ev.HashedPassword, evnt.HashedPassword)
.Set(ev => ev.Salt, evnt.Salt));
The code looks little ugly and redundant to me: with all that lambda stuff we still need to provide property values explicitly. Another way is to replace PasswordChangedEvent with User dto, so we do not need event mapping anymore:
MongoCollection.Update(Query<ReadDto.User>.EQ(u => u.Id, evnt.AggregateId),
Update<ReadDto.User>.Set(u => u.HashedPassword, evnt.HashedPassword));
So the question again: is there any better way to do such a type of mapping? Two types of objects (Events and DTO) mapped to the same mongo db collection.
It seems like this is actually a question about mapping data from one object to another?
If so, you may want to consider using something like Ditto or AutoMapper. I am the developer of ditto and have used it for a number of CQRS systems effectively...I wrote it to handle mixing in alot of different objects' data into the same View Model.
These are known as OO mappers and typically have some form of bootstrapping configuration code, often using sensible conventions to avoid all the redundancy.

Categories