I am trying to adapt singleton policy for my CsvConfiguration Property.
If the configuration is already available, just return the configuration. else, get the configuration and return the same and I am able to build this code.
public Rootpdf pdfConfiguration
{
get
{
Rootpdf pdfConfiguration = null;
try
{
if (pdfConfiguration == null)
{
//retrieve the configuration file.
//load the configuration and return it!
}
else
{
return pdfConfiguration;
}
}
catch (Exception e)
{
Log.Error("An error occurred while reading the configuration file.", e);
}
return pdfConfiguration;
}
}
Advantages (i hope): Whenever my pdfConfiguration is wanted, if already it is available, i can return it. Need not load the configuration file eachtime
and calculate the configuration.
My Query: The resharper! The resharper tells that the code
if (pdfConfiguration == null) //The expression is always true.
Is it really a problem with resharper that it doesn't understand I am following this singleton pattern ?
or
Am I not following singleton pattern at all?
You're setting the singleton to null at the top of your get clause:
Rootpdf pdfConfiguration = null;
//THIS IS THE PROBLEM.
Note: 99% of the time, ReSharper is smarter than you. I don't like it, but it's true.
think you have to use a local variable out of the getter
private static Rootpdf _pdfConfiguration ;
public static Rootpdf pdfConfiguration
{
get
{
try
{
if (_pdfConfiguration == null)
{
//retrieve the configuration file.
//load the configuration and return it!
}
else
{
return _pdfConfiguration;
}
}
catch (Exception e)
{
Log.Error("An error occurred while reading the configuration file.", e);
}
return _pdfConfiguration;
}
}
and as you want a singleton, i made it a static property... hope it's what you need.
Here is what your class should look like:
public class RootPdf
{
private static RootPdf instance;
private RootPdf()
{
//retrieve the configuration file.
//load the configuration and return it!
}
public static RootPdf Instance
{
get
{
if (instance == null)
{
try
{
instance = new RootPdf();
}
catch (Exception e)
{
Log.Error("An error occurred while reading the configuration file.", e);
return null;
}
}
return instance;
}
}
}
And here is how you will call the object:
var pdf = RootPdf.Instance;
class MySingletonClass
{
private static UserSettings instance = null;
/// <summary>
/// Default protected constructor.
/// </summary>
protected MySingletonClass()
{
}
/// <summary>
/// Invoke the singleton instance.
/// </summary>
public static MySingletonClass Instance()
{
if (instance == null)
instance = new MySingletonClass();
return instance;
}
}
This woud be invoked/instanciated like
MySingletonClass msc = MySingletonClass.Instance();
You can also use an accessor/Property to return the instance
public MySingletonInstance Instance
{
get
{
if (instance == null)
instance = new MySingletonInstance();
return instance;
}
}
Where this is invoked/instantiated via
MySingletonClass msc = MySingletonClass.Instance;
I like the first method of the above.
I hope this helps.
As already mentioned this is a not a singleton pattern.
If you want to stick with the idea you described then I would change your code to :
internal class Config
{
private readonly Lazy<Rootpdf> _config;
public Config()
{
_config = new Lazy<Rootpdf>(ReadConfiguration);
}
private Rootpdf ReadConfiguration()
{
throw new NotImplementedException();
}
public Rootpdf pdfConfiguration
{
get
{
try
{
return _config.Value;
}
catch (Exception e)
{
Log.Error("An error occurred while reading the configuration file.", e);
}
return null;
}
}
This line: if (pdfConfiguration == null) will always be true due to this line (just before) Rootpdf pdfConfiguration = null;. What you need to do is to place the last line (Rootpdf pdfConfiguration = null;) outside the Get method. This will stop the variable to be initialized to null each time.
private static Rootpdf pdfConfiguration = null;
public Rootpdf PdfConfiguration
{
get
{
try
{
if (pdfConfiguration == null)
....
More information on the Singleton Pattern is available here.
Alternatively, you can use a Static Constructor:
A static constructor is used to initialize any static data, or to
perform a particular action that needs to be performed once only. It
is called automatically before the first instance is created or any
static members are referenced.
public class Foo {
private static Rootpdf pdfConfiguration = null;
static Foo()
{
pdfConfiguration = ....
}
public Rootpdf pdfConfiguration
{
get
{
return pdfConfiguration;
}
....
Nowadays , I think since C# 6.0, you can use initial values with properties, like this:
static public Rootpdf pdfConfiguration { get; } = new Func<Rootpdf>(() => {
//retrieve the configuration file.
//load the configuration and return it!
return new Rootpdf(); // Something like this perhaps..?
})();
Related
Is it possible to pass the generic type from one class to other class generic property.
For example:
Assembly Logger
namespace Logger
{
public class GenericLoger<T>
{
T _genericLog;
LogManager _logManager;
public GenericLoger(string logName)
{
_logManager = new LogManager(logName);
//Assigning the generic type to Log.GenerciLog, this is how I am
expecting or by some other possible way?.
Log.GenerciLog = _genericLog;
}
public static Write(string description)
{
_logManager.write(description);
}
}
public static class Log
{
LogManager _logManager;
static Log()
{
_logManager = new LogManager();
}
public static Write(string description)
{
_logManager.write(description);
}
//The generic type supplied in GenericLoger need to pass here,
//like this or by some other possible way?
public static T GenerciLog { get; internal set; }
//T is unrecognized here as type is available in GenericLoger
//I want to pass here from GenericLoger
}
}
Assembly Main Caller of Logger
using Logger;
namespace DataProcessor
{
internal class SpecialLogger
{
private static Lazy<GenericLog<SpecialLogger>> _passed;
public static GenericLog<SpecialLogger> Passed
{
get
{
if (_passed == null)
{
_passed = new Lazy<GenericLog<SpecialLogger>>(() => new GenericLog<SpecialLogger>("Passed"), true);
}
return _passed.Value;
}
}
private static Lazy<GenericLog<SpecialLogger>> _failed;
public static GenericLog<SpecialLogger> Failed
{
get
{
if (_failed == null)
{
_failed = new Lazy<GenericLog<SpecialLogger>>(() => new GenericLog<SpecialLogger>("Failed"), true);
}
return _failed.Value;
}
}
}
internal class Processor
{
public void ProcessRate()
{
var trans = dataManager.GetData();
//Will write the log in "Log.txt" file
Log.write(trans.Count + " transaction found");
foreach (var item in trans)
{
try
{
//transaction process code here
//This will write the text in "Passed.txt" file. 'Passed' property I want to access like this
Log.GenerciLog.Passed.Write(item);
}
catch (Exception ex)
{
//This will write the text in "Failed.txt" file. 'Failed' property I want to access like this
Log.GenerciLog.Failed.Write(item);
}
}
}
}
}
NOTE: In .NET you don't have a way for automatic type inference for use case like yours, also there is no automatic type substitution.
Not sure if this is what you are looking for
Your method definition should look like this
public static T GenerciLog<T> { get; internal set; }
and this is how to call it
try
{
//transaction process code here
//This will write the text in "Passed.txt" file. 'Passed' method I want to access like this
Log.GenerciLog<SpecialLogger>.Passed.Write(item);
}
catch (Exception ex)
{
//This will write the text in "Failed.txt" file. 'Failed' method I want to access like this
Log.GenerciLog<SpecialLogger>.Failed.Write(item);
}
This is a very simple log class. There is a lot more you could do with this sort of thing. Its all provided by log4net which I'd recommend using rather than trying to write your own logger. But the below is a start of how I'd implement a simple logger. It allows you to log to several different things at once. I appreciate the below doesn't answer exactly what you want but its an indication of how to start and you can adapt it to suit your needs.
public static class Logger
{
private static List<ILogger> _loggers = new List<ILogger>();
public static void Log(string message)
{
foreach (var logger in _loggers)
logger.Write(message);
}
public static void AddLogger(ILogger logger)
{
_loggers.Add(logger);
}
}
public interface ILogger
{
void Write(string message);
}
public class SpecialLogger : ILogger
{
public void Write(string message)
{
//special log code here eg
Console.WriteLine(message);
}
}
then somewhere do this
Logger.AddLogger(new SpecialLogger());
Logger.Log("A log message");
Am I able to use an instance of once class in another class and file without having to reinstantiate it?
class Start
{
public static Log Log = new Log(...);
}
class Start1
{
Log.Write("New instance!");
}
I have read about having to use a get/set block to do it, but I'm not exactly sure how I would go about that,
Singleton pattern:
public class Log
{
private static Log instance;
private Log() { }
public static Log Instance
{
get
{
return instance ?? (instance = new Log());
}
}
}
Use it by calling Log.Instance, and so on.
To call this using a parameter, you need to do something like this:
public class Log
{
private string foo;
private static Log instance;
public static Log Instance
{
get
{
if (instance == null)
{
throw new InvalidOperationException("Call CreateInstance(-) to create this object");
}
else
{
return instance;
}
}
}
private Log(string foo) { this.foo = foo; }
public static Log CreateInstance(string foo)
{
return instance ?? (instance = new Log(foo));
}
}
However, it is generally a bad idea to use singletons in this manor. Have a look at dependency injection / inversion of control to see how this can be solved.
I have got this singleton implementation in MVC project:
public sealed class Singleton<T> where T : class {
private static volatile T _instance;
private static object _lock = new object();
static Singleton() {}
public static T Instance {
get {
if (_instance == null)
lock (_lock) {
if (_instance == null) {
ConstructorInfo constructor = null;
try {
// Binding flags exclude public constructors.
constructor = typeof(T).GetConstructor(BindingFlags.Instance | BindingFlags.NonPublic, null, new Type[0], null);
}
catch (Exception exception) {
throw new SingletonException(exception);
}
if (constructor == null || constructor.IsAssembly) // Also exclude internal constructors.
throw new SingletonException(string.Format("A private or protected constructor is missing for '{0}'.", typeof(T).Name));
_instance = (T)constructor.Invoke(null);
}
}
return _instance;
}
}
}
Then I have a controller and this Instance method
public static Controller Instance {
get { return Singleton<Controller>.Instance; }
}
In controller constructor I want to load something like this
private Controller() {
int id = Controller.Instance.SqlManager.GetId();
}
This gives me a loop of course and I don't know how to escape from this.
IMHO access via Controller.Instance is for the clients of Controller, internally you should use the controller fields and methods directly, you don't need to know whether your class is being used as a singleton or not.
I am trying to initialize a static variable from a static method but after it has been initialized it is still null. What am I doing wrong?
class Database {
public static Database Connection = null;
public static void Create() {
Database.Connection = new Database();
if (Database.Connection == null) {
Console.WriteLine("Null");
}
}
public Database() {
Console.WriteLine("I got called");
}
}
Am I missing something here? Database.Connection is NULL after calling the method although the constructor has been called.
class Database {
public static Database Connection = null;
static Database() {
Database.Connection = new Database();
if (Database.Connection == null) {
Console.WriteLine("Null");
}
}
public Database() {
Console.WriteLine("I got called");
}
}
You never call the Create(). You can use static constructor for this, if you'd like, as I've done above.
Use Static constructor, to initialize static field.
static Database()
{
Database.Connection = new Database();
}
One option is to make the static member a Property:
class Database
{
private static Database _connection = null;
public static Database Connection
{
get
{
if(null == _connection)
{
_connection = new Database();
}
return _connection;
}
}
}
If you are implementing a singleton, then you should hide the constructor by making it private.
private Database()
{
// This will only be called once, when the Connection
// property getter is first accessed and the private
// _connection field is still null. Note: when using
// the debugger, this may be before it is actually called
// explicitly from within your code!
Console.WriteLine("Database() constructor called");
}
I have the following class with a nested private class and I would like to assign the value of NID to Context. I have used getters and setters however the value of NID (Sequencer.Context = value;) never gets assigned to ( SeqNode = Node.LoadNode(Context); ). What am I doing wrong?
//Instantiation
Increment.NID = "/Root/Dir/NodetoIncrement";
String getSequence = Convert.ToString(Increment.SID);
// The Class
public static class Increment
{
//Value of the node Context location in the tree to increment ( Increment.NID )
public static string NID
{
set { Sequencer.Context = value; } //The "/Root/Dir/NodetoIncrement";
}
//Get the sequence ID
public static int SID
{
get { return Sequencer.GetSeqId; }
}
//Nested sequencer class. This increments the node.
private class Sequencer
{
private Node SeqNode;
private static int SequenceNumber;
private volatile bool Run = true;
public static string Context { get; set; } //gets
public static int GetSeqId
{
get
{
return Interlocked.Add(ref SequenceNumber, 1);
}
}
public Sequencer() //Constructor Here!
{
SeqNode = Node.LoadNode(Context);
SequenceNumber = Convert.ToInt16(SeqNode["LastSequenceNo"]);
//NEVER DO THIS .. causes the system to lockup see comments.
System.Threading.Tasks.Task.Factory.StartNew(() =>
{
while (Run)
{
Save();
Thread.Sleep(5000);
}
});
}
private void Save()
{
//optimistic concurrency recommended!!
var retryMaxCount = 3; // maximum number of attempts
var cycles = 0; // current attempt
Exception exception = null; // inner exception storage
while (cycles++ < retryMaxCount) // cycle control
{
try
{
SeqNode["LastSequenceNo"] = Convert.ToString(SequenceNumber);
SeqNode.Save();
// successful save, exit loop
exception = null;
break;
}
catch (NodeIsOutOfDateException e)
{
exception = e; // storing the exception temporarily
SeqNode = Node.LoadNode(Context);
}
}
// rethrow if needed
if (exception != null)
throw new ApplicationException("Node is out of date after 3 attempts.", exception);
}
~Sequencer() { Save(); }
}
}
public class XYHandler : Node
{
public override void Save(NodeSaveSettings settings)
{
base.Name = Convert.ToString(Increment.SID);
base.Save();
}
public override bool IsContentType
{
get { return true; }
}
}
What am I doing wrong?
You are waiting for another thread in a static initializer. NEVER DO THAT. I can't emphasize strongly enough how insanely dangerous that is.
For an explanation why, see this answer:
https://stackoverflow.com/a/8883117/88656
Is there some temporal coupling at play here?
SeqNode is set when the Sequencer is instantiated, but I can't see an instantiation in your sample.
The static constructor will run before the property setter is invoked the first time, and then try again 5s later - when is the property being set?
I can't see where Sequencer is being constructed (perhaps I missed it). Since it isn't a static constructor it will have to be called at least once for LoadNode to run. Did you intent to make that constructor static also?