Global Settings in Application - c#

On a ASP.NET MVC application with multiple assemblies I need to access a few settings.
Basically. the settings are constants or values from Web.Config AppSettings.
My idea is to inject a Settings class, as a singleton, in places where I need it:
public interface ISettings {
LoggerSettings Logger { get; }
} // ISettings
public class LoggerSettings {
public String Levels { get { return ConfigurationManager.AppSettings["Logger.Levels"]; } }
public const String Report = "team#xyz.com";
} // LoggerSettings
public class Settings : ISettings {
public LoggerSettings Logger { get; private set; }
public Settings() {
Logger = new LoggerSettings();
}
} // Settings
What do you think about this approach and injecting the class as a singleton?
Do I need, in this case, to set any class/property as static?
I think I need to have LoggerSettings and its properties as static, not?
Otherwise I will need to create a new instance when constructing the Settings?
Could someone, please, advise me on this?

If you are actually injecting your class (via a DI framework), and by "singleton" you mean you are using a singleton "scope" in your DI framework, then this approach will work just fine. If this in fact what you are doing, then none of your properties need to be static, as the same "singleton" instance will be injected into any class that depends on it.

Related

Injecting Dependency in Method in ASP.NET Core

I have the following scenario:
I got a service ICompanyDocumentsService with a single implementation CompanyDocumentsServicewhich I register in my Startup class:
public void ConfigureServices(IServiceCollection services)
{
services.AddScoped<ICompanyDocumentService, CompanyDocumentService>();
}
I need this service in many places, and it doesn't bother me using DI in Constructor.
However, there is one place where I need it injected in a Method (or probably in a property would be even better):
public abstract class CompanyDocumentBase
{
public abstract object GetAllProperties(Employee employee, string properties,
CompanyDocumentReferenceData documentReferenceData);
// blah, blah, lots of Formatting Methods
private CompanyDocumentService CompanyDocumentService { get; set; } // **inject service here**
public string GetFormattedEmployeeIndividualEmploymentAgreementNumber(Employee employee,
ICompanyDocumentService companyDocumentService = null) // **optional because
//inherited class doesn't need to know anything about this service, it concerns only it's result**
{
companyDocumentService = CompanyDocumentService;
var test =
companyDocumentService.GetEmloyeeIndividualEmploymentAgreementNumber(employee.Id);
return string.Empty;
}
}
There are many classes inheriting CompanyDocumentBase which are only concerned in it's method results, as mentioned above, that's why that parameter is optional, and that's why I don't need injecting DI in constructor, thus the inheriting classes won't be needing that.
public class JobDescriptionCompanyDocument : CompanyDocumentBase
{
public override object GetAllProperties(Employee employee,
string properties, CompanyDocumentReferenceData documentReferenceData)
{
var document = JsonConvert.DeserializeObject<JobDescriptionModel>(properties);
document.IndividualEmploymentAgreementNumber = GetEmployeeIndividualEmploymentAgreementNumber(employee);
return document;
}
}
Is there any simple way to achieve this? Preferable without needing to install a separate library like Unity or Autofac.
Ideal it would be to somehow get the instance of CompanyDocumentsService directly into that property, something like:
private CompanyDocumentService CompanyDocumentService => Startup.Services.blah that instance
One hack way (personally I wouldn’t recommend it), is after your container is built, you could resolve an instance of IHttpContextAccessor and set it to static class, e.g. IoC
Then you could do private CompanyDocumentService CompanyDocumentService => IoC.HttpContextAccessor.HttpContext.RequestServices.GetService().
https://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.http.httpcontext.requestservices?view=aspnetcore-3.1
The interface is a singleton, and provides access to scoped services from a static context.
Note you might have to explicitly register HttpContextAccessor:
https://learn.microsoft.com/en-us/aspnet/core/fundamentals/http-context?view=aspnetcore-3.1
UPDATE
What I'd recommend
If you are open to object factories, and changing the way how DocumentBase is instantiated, try make a factory, and whenever you need an instance of DocumentBase, only use the factory to create it:
public abstract class CompanyDocumentBase
{
// Use internal so that access only limited to friendly assembly
internal CompanyDocumentService CompanyDocumentService { get; set; }
}
// Inject this class to where you need to create an instance of CompanyDocumentBase
public class CompanyDocumentFactory<T> where T : CompanyDocumentBase
{
private readonly IServiceProvider _services;
// DI contaiener has implicit IServiceProvider support, when you do this on constructor, it injects service provider of *current* scope
// If this factory is registered as singleton, you need to use IHttpContextAccessor to use request's service provider in Create method
// because your DocumentService is scoped.
public CompanyDocumentFactory(IServiceProvider services)
{
_services = services;
}
public T Create()
{
// Create an instance of document use your current method.
var instance = new T();
instance.CompanyDocumentService = _services.GetRequiredService<ICompanyDocumentService>();
return instance;
}
}

How to register manually-created decorator instance

Typically, to register some configuration value using constructor injection I would do this:
string setting = ConfigurationManager.AppSettings["SomeSetting"];
container.Register<IService>(new Service(setting));
How do you accomplish something similar, in order to pass a configuration value into a decorator constructor?
Is the only means to create some configuration provider class which could get injected into the decorator? Seems like RegisterDecorator should have an overload which allows manually newing the class as needed.
There are several ways to achieve this. If that part of the object graph is simple, building the object graph by hand might give the best results:
container.RegisterSingleton<IService>(new ServiceDecorator(
setting,
new RealService()));
// or
container.Register<IService>(() => new ServiceDecorator(
setting,
new RealService()));
There is no delegate overload for RegisterDecorator in Simple Injector, which means that you can't register a decorator using RegisterDecorator that is hand-wired, but there some alternative approaches.
You can extract the setting value into its own class. This allows the that abstraction to get injected into the decorator:
container.RegisterSingleton<MySetting>(new MySetting(setting));
container.RegisterDecorator(typeof(IService), typeof(ServiceDecorator));
public ServiceDecorator : IService {
public ServiceDecorator(MySetting setting, IService decoratee) { }
}
Or you can inject the setting into a property of the decorator:
container.RegisterDecorator(typeof(IService), typeof(ServiceDecorator));
container.RegisterInitializer<ServiceDecorator>(dec => dec.Setting = setting);
public ServiceDecorator : IService {
public string Setting { get; set; }
public ServiceDecorator(IService decoratee) { }
}
Or you can make the Setting a static property:
ServiceDecorator.Setting = setting;
container.RegisterDecorator(typeof(IService), typeof(ServiceDecorator));
If the decorator itself can't be changed, you can derive from that class:
public ServiceDecoratorWithSetting : ServiceDecorator {
public static string Setting { get; set; }
public ServiceDecorator(IService decoratee) : base(Setting, decoratee) { }
}
ServiceDecoratorWithSetting.Setting = setting;
container.RegisterDecorator(typeof(IService), typeof(ServiceDecoratorWithSetting));
A last option is to override parameter injection behavior, but that's a bit more complex, and I usually only advice this in integration scenarios.

Global instance with readonly property

I want to implement a class whose instance is global but whose property is to be initialized only once during the run time.
Also the initialization is to be done as an assignment from a result of function during execution.
Basically I want to do something like this
public class Configuration
{
public string param1 { get ; set; }
public int param2 { get; set; }
}
public static class AppConfig
{
public static readonly configuration;
}
public class Initialize
{
public void InitConfig()
{
AppConfig.configuration = GetParamsFromDB();
}
}
But I am unable to figure out how to implement it. Please ignore the above incorrect representation. It is just to present what is required.
EDIT
Also there is a need of seperate class Initialize because classes Configuration and AppConfig are in dll BO. GetParamsFromDB() is in DAL. DAL references BO hence
BO cannot refere DAL hence GetParamsFromDB() cannot be used within AppConfig class
All you need to do is initialize it inline:
public static class AppConfig
{
public static readonly configuration = GetParamsFromDB();
}
The C# runtime will automatically ensure that the parameter isn't initialized until the class is accessed for the first time, giving you your desired behvaior.
Note that your configuration type is mutable, which if you want to ensure these values aren't changed, is a bad thing. You should refactor your configuration class to accept the two values in its constructor and not provide public setters for the properties.
It looks like you want a singleton.
See: Implementing the Singleton Pattern in C#
public static class AppConfig
{
private static readonly Lazy<Configuration> _configuration = new Lazy<Configuration>(() => new Configuration());
public static Configuration Instance { get { return _configuration.Value; } }
}
However, you should consider changing your design as singletons are often overused.
Consider something that can be used with dependency injection and inversion of control.
Dependency injection is a pattern that increases code reuse and minimize dependencies through interfaces.
Inversion of control is a pattern that binds objects together at runtime typically using an assembler object.
Example:
public interface IAppConfig
{
Configuration Configuration { get; }
}
public sealed class AppConfig : IAppConfig
{
private readonly Configuration _configuration;
public AppConfiguration()
{
_configuration = new Configuration { };
}
public Configuration Configuration { get { return _configuration; } }
}
This can be used together with an IoC Container to provide configuration to all the objects that need it.
What you are trying to do is kind of Singleton Pattern, It can be implemented as follows,
public sealed class Configuration
{
private static volatile Configuration instance;
private static object syncRoot = new Object();
private Configuration() {}
public static Configuration Instance
{
get
{
if (instance == null)
{
lock (syncRoot)
{
if (instance == null)
instance = new Configuration();
}
}
return instance;
}
}
}

how to use dependency injection to provide data that is required by several classes

several classes in my dll require a set of the data ( general configurations ) . these data are provided by the one who uses the dll through implementing an interface IConfigs . so data should be injected as a dependency . now I wonder how to do that .
Update :
sorry , if the question was not clear . the problem is should I have an instance of IConfigs in each class that needs it and using constructor injection ( that I don't like this approach ) or there is a cleaner way to handle this situation ?
You can use injection dependency by property.
If you use MEF :
Service
[Export(typeof(IServiec))]
public class Service : IService
{
....
}
Client
public class Client
{
[Import]
public IService Service
{
}
}
Nota : You add lines in order to register your catalog and container
If I understand you correctly, you want do register different derived classes with one interface, don't know what IoC Container you uses, but in here I uses Unity as in sample code, but most of other IoC Containers support using one string to differentiate registration in one interface. Assume you have:
public interface IConfig {}
public class ConfigA : IConfig {}
public class ConfigB : IConfig {}
So you can register both ConfigA and ConfigB to IConfig with different name:
var container = new UnityContainer();
container.RegisterType<IConfig, ConfigA>("A");
container.RegisterType<IConfig, ConfigA>("B");
public class MainClass
{
private IConfig _config;
public MainClass([Dependency("A")] IConfig config)
{
_config = config;
}
}
If you don't want to use constructor dependency, use property:
public class MainA
{
[Dependency("A")]
private IConfig Config { get; set; }
}
As your helper classes are static, you won't be able to use DI unless you use a ServiceLocator style and have your helper class retrieve injected values itself, something like this:
public static class HelperClass
{
static HelperClass()
{
var config = ServiceLocator.Get<IConfig>();
UserId = config.Get("UserId");
}
public static int UserId { get; private set; }
}
This is not considered good practice because your helper class then has a hidden dependency on your ServiceLocator being set up with an IConfig which contains a UserId.
I'd therefore recommend you change your helper class to be non-static, and have the IConfig it needs injected into it via its constructor, like this:
public class HelperClass
{
public HelperClass(IConfig config)
{
UserId = config.Get("UserId");
}
public int UserId { get; private set; }
}
You can then inject your HelperClass into your service classes via their constructors, like this:
public class ServiceClass
{
private readonly HelperClass _helperClass;
public ServiceClass(HelperClass helperClass)
{
_helperClass = helperClass;
}
}
This way each component can be swapped out, stubbed or mocked as necessary. If your HelperClass has no state of its own you can configure your DI container to manage it with a Singleton lifetime, which essentially makes it 'static' with none of the disadvantages.

Circular reference problem Singleton

I'm trying to creating a Singleton class like below where MyRepository lies in separate DAL project. It's causing me a circular reference problem because GetMySingleTon() method returns MySingleTon class and needs its access. Same way I need MyRepository access in constructor of MySingleTon class.
public class MySingleTon
{
static MySingleTon()
{
if (Instance == null)
{
MyRepository rep = new MyRepository();
Instance = rep.GetMySingleTon();
}
}
public static MySingleTon Instance { get; private set; }
public string prop1 { get; set; }
public string prop2 { get; set; }
}
UPDATE: I was doing it very wrongly.
I think didn't needed any singleton. Now I've created a class with static properties in a third project and I'm setting it once and accessing it everywhere. And it has solved my problem for now.
Thanks everyone for your answers.
The repository should not return a singleton object, a repository is used to access data and not returning singleton objects. Your repository could by itself be a singleton, but I don't recommend it, and I don't recommend using a singleton for the class using the repository either. In the code you have it seems like the repository needs to be aware of the "business layer" which is all messed up, the relationships should go only one way. I would re-write it as:
public class MySingleTon
{
private MySingleTon()
{
// You constructor logic, maybe create a reference
// to your repository if you need it
}
private static MySingleTon _instance;
public static MySingleTon Instance {
get
{
if(_instance == null)
_instance = new MySingleTon();
return _instance;
}
}
public string prop1 { get; set; }
public string prop2 { get; set; }
}
I don't recommend my solution, but it should solve you problem. What I do recommend is looking into dependency injection and inversion of control since your design seems sort of wrong. Have a look at NInject.
EDIT: One other thing, why does your singleton have several properties that are public? A singleton shouldn't expose properties it should only expose functions, and should mainly be used when you have a utility class like Math or a true singleton like a logger.
Although , it is not good to create such a class intraction and i don't know what is the reason behind this.
but you can do similar to the below code
Create a project called Public Interface and define an interface IMyRepository with the public functions which you want to expose from MyRepository class.
Create a public property in the singleton class which returns IMyRepository and can be set outside the assembly also.
Now , you need to explicitly set this property from the assemblies which reference your singelton assembly and i assume you can create the object of MyRepository class from other assemblies.
Please note : Above solution is only a trick to break the circular reference not the optimal solution.
While having the singleton accessor property within the class itself is a generally used shortcut, in more complicated situations when you need to deal with instances of multiple related classes it may prove the wrong way. The problem is mixing concerns within a single class.
Your MySingleton class shall be rather some MyClass which is implemented in way generally not dependent on the number of instances that will exist on run-time. Likewise MyRepository shall be able to manage and provide any number of MyClass instances. The fact you will be dealing with only a singleton instance of MyClass can be encapsulated into a separate factory (or accessor or whatever you call it) class that will bind MyClass and MyRepository together.
So try to rethink your design in the following way (schematic):
public class MyClass { ... }
public class MyRepository
{
public MyClass GetMyClassInstance(...);
}
public static class MyClassFactory
{
public static MyClass SingletonInstance
{
get
{
if (singletonInstance == null)
singletonInstance = myRepository.GetMyClassInstance(...);
return singletonInstance;
}
}
}
The remaining question is where does myRepository come from. For example, it can be created on program start-up and provisioned into MyclassFactory as a member field.
At the end of the day, a lot can be made easier if you consider using an inversion of control container. The next step is also shift towards interface-based design. That gives you another layer of abstraction and provides more flexibility in terms of interchangeability of implementations.
in addition to the code from Saurabh, you will change the Singleton class by :
public class MySingleTon
{
static MySingleTon()
{
if (Instance == null)
{
Instance = new MySingleTon();
}
}
private MySingleTon(){}
public static MySingleTon Instance { get; private set; }
public IMyRepository MyRepository{ get; set ;}
}

Categories