I am creating asp.net web service. I have one class, whose static constructor is not getting called when I try to initialize object of that class. I am not able to understand this behavior. Inside static constructor I am reading values from web.config file.
Here is part of code :
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class Service : System.Web.Services.WebService
{
AppController extractor;
public Service()
{
try
{
extractor = new AppController();
}
catch(Exception ex)
{
// I am not getting exception at this point.
}
}
}
public class AppController
{
static string converterBatchFilePath = null;
static string personalProfileOutputFolderPath = null;
static AppController()
{
// reading some settings from web.config file
try
{
converterBatchFilePath = ConfigurationManager.AppSettings["WordToTextConverterBatFilePath"];
}
catch(Exception ex)
{ // }
}
public AppController()
{
// do some initialization
}
}
While debugging web service I noticed that only instance constructor is getting called and control never goes to static constructor.
Anyone know why this is happening?
I am using VS 2008 Express edition and C#.
EDIT
Actually this AppController is console based project. I have added that project as a reference inside Web service project and then using it. If I use AppController from command line, it works fine, but its not working from inside web service project.
My guess is that it's called before you expected it to be called. If you have already debugged your site but not recycled the AppPool, it's very likely that the static constructor has already been run.
Similarly anything that accesses any static members will also call the static constructor if it hasn't already been called.
Today my static initializer was not being called. It turns out static initializers are not called prior to accessing const members of a class.
Since const values are known at compile time this makes sense, but it means that the documentation which states "It is called automatically before ... any static members are referenced" is technically incorrect, at least when combined with #JonSkeet's assertion that "All constants declarations are implicitly static".
This program demonstrates the problem:
using System;
static class Program
{
public static void Main()
{
Console.WriteLine("Constant={0}", Problem.Constant);
Console.WriteLine("ReadOnly={0}", Problem.ReadOnly);
Console.WriteLine("Field={0}", Problem.Field);
Console.WriteLine("Property={0}", Problem.Property);
}
private static class Problem
{
public const int Constant = 1;
public static readonly int ReadOnly = 2;
public static int Field = 3;
private static int mProperty = 4;
public static int Property { get { return mProperty; } }
static Problem()
{
Console.WriteLine("Problem: static initializer");
}
}
}
The output is:
Constant=1
Problem: static initializer
ReadOnly=2
Field=3
Property=4
(Tested against .NET 4.5.)
I suspect that your problem is caused by an exception being raised in your static constructor and being swallowed by the code that creates the instance.
Potentially even an exception in a static field initializer which are even harder to debug.
Perhaps enabling breaking on first-chance exceptions helps debugging the problem.
I would not put code that reads from a config file into a static constructor at all. I'd instead encapsulate all config dependent stuff you have in a class and pass an instance of that class into your constructor, probably using an IoC container.
This has a number of advantages:
You can use different configurations in the same AppDomain at the same time
You can use alternate ways of loading the configuration
You don't need to do complex stuff that might fail in a static constructor. As you have seen static constructors tend to be problematic to debug, so I'd do only simple initializations that don't depend on external state there
(I know this is not an answer, but it's too long for a comment)
A static constructor is used to initialize any static data, or to perform a particular action that needs performed once only. It is called automatically before the first instance is created or any static members are referenced.
Please note that
a static constructor is called automatically to initialize the class before the first instance is created or any static members are referenced. and the user has no control on when the static constructor is executed in the program.
Taken from MSDN's Static Constructors (C# Programming Guide) .
Here's a quick sample I put together to get values from a config file in your extractor class, both in the static and instance constructors. This works for me -- compare it against what you're doing and see what's different:
public class Service : System.Web.Services.WebService
{
AppController extractor;
[WebMethod]
public string HelloWorld()
{
extractor = new AppController();
return AppController.staticString + " :: " + extractor.instanceString;
}
}
class AppController
{
public static string staticString;
public string instanceString;
static AppController()
{
staticString = System.Configuration.ConfigurationManager.AppSettings["static"];
}
public AppController()
{
instanceString = System.Configuration.ConfigurationManager.AppSettings["instance"];
}
}
My web.config:
<appSettings>
<add key="static" value="blah blah"/>
<add key="instance" value="ha ha"/>
</appSettings>
My response:
<?xml version="1.0" encoding="UTF-8"?>
<string xmlns="http://tempuri.org/">blah blah :: ha ha</string>
When I was trying to debug by placing a breakpoint on the line where the static field had referenced, I was not getting debug control on the static constructor.
I kept breakpoint on the static constructor entrance, removed the breakpoint from the line where the static field had referenced. Now Debug control started coming into the static constructor code.
This image shows how your editor with breakpoints would look like
Related
I have done a lot of reading on instance vs. static classes and have not found an answer to my question. Are there any perils to instancing a different class in a static class that was referenced by an instance class?
The current design I am working with is one in which instance classes call a static "Logger" method (passing a series of parameters) to log errors to a text file in the file system. I am refactoring the static "Logger" method to instantiate a parameter class (which is just a series of properties and a few helper methods to return itself as XML or a string) and a DBLogger class to log the error to the database rather than the file system, passing the parameter class as the sole parameter.
This model worked well in my legacy VB6 code, in which the Logger class was instanced, not static.
But now in the .NET code I am not sure if I should make my 2 new classes (parameter and DBLogger) static, or just make the DBLogger static and instance the parameter class. I am concerned about the potential for concurrency/multi-thread data issues with (or without) instances being created from a static class. Am I right to be concerned or am I worrying about nothing?
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
// all code truncated for illustration purposes
namespace ThisIs.A.Test
{
//INSTANCE
public class ErrorLogParameters
{
private int mThreadId = 0;
private int mErrorNumber = 0;
private string mServerDate = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff");
public int ThreadId
{
get { return mThreadId; }
set { mThreadId = value; }
}
public int ErrorNumber
{
get { return mErrorNumber; }
set { mErrorNumber = value; }
}
public string ServerDate
{
get { return mServerDate; }
}
}
//INSTANCE
public class ErrorLog
{
public void LogErrorToDatabase(ErrorLogParameters criteria)
{
//Log error to database here
}
}
//STATIC - Instantiates INSTANCE of ErrorLogParameters and ErrorLog
public class Logger
{
public static void WriteLog(string pstrObjectName, string pstrProcedureName, int plngErrNumber, string pstrErrDescription)
{
// create a new parameter object
ErrorLogParameters objParameters = new ErrorLogParameters();
// populate object properties
objParameters.ErrorNumber = mlngErrNumber;
objParameters.ThreadId = System.Threading.Thread.CurrentThread.ManagedThreadId;
ErrorLog objErrorLog = new ErrorLog();
objErrorLog.LogErrorToDatabase(objParameters);
}
}
//INSTANCE - Invokes STATIC method
public class SomeInstance
{
private void ErrorHandler_Log(Exception exception, string procedureName, string additonalDescription, string stackTrace)
{
// call from instance class to static class
Logger.WriteLog(mstrObjectName, procedureName, mlngErrNumber, mstrErrDescription);
}
}
}
No, that's absolutely fine - if you're creating an instance of any class within a method, it doesn't matter whether the class declaring that method is a static class or not.
Furthermore, unless you've got something "special" (e.g. a static variable counting the number of instances created) you're less likely to run into concurrency issues when creating new objects than when using existing objects. Basically, the tricky part of almost all concurrency is working out where mutable data is shared - it doesn't sound like you've got any here (although sample code would help to clarify that).
I would use a combination of the provider and singleton pattern for this.
Create an abstract class called Logger.
The Logger class contains abstract methods for writing to log. For example:
abstract void LogInfo(LogInfo info);
abstract void LogError(Exception exception);
etc
The Logger class contains a private instance of Logger object.
The Logger class contains a static property that returns the private instance.
The Logger class contains a static constructor that instantiate the private instance of Logger object. You would probably use Reflection and instantiate the object based on the configuration.
Implement a FileLogger that inherits from the Logger object. This logger writes to a file.
Implement a SQLLogger that inherits from the Logger object. This logger writes to a database.
Call the logger like so:
Logger.Instance.WriteInfo(info);
Logger.Instance.WriteError(exception);
There are a few advantages of using this design:
Your logging functionality is fully abstracted. This completely decouple the logging callers from the code that writes the logs. This allows you to write the log to any data stores.
You can change which logger to use without compiling the code. Just update the config file.
Singleton guarantees thread-safety
Testability. You can write Mock tests against abstract classes.
Hope this helps.
There are no concurrency issues with static methods.
Static variables are a different matter.
I want to write unit test for below class.
If name is other than "MyEntity" then mgr should be blank.
Negative Unit test
Using Manager private accessor I want to change name to "Test" so that mgr should be null.
And then will verify the mgr value.
To achieve this, I want to explicitly call the static constructor
but when I call the static constructor using
Manager_Accessor.name = "Test"
typeof(Manager).TypeInitializer.Invoke(null, null);
name is always set to "MyEntity" how to set name to "Test" and invoke the static constructor.
public class Manager
{
private static string name= "MyEntity";
private static object mgr;
static Manager()
{
try
{
mgr = CreateMgr(name);
}
catch (Exception ex)
{
mgr=null;
}
}
}
As I found out today, the static constructor CAN be called directly:
from another Stackoverflow post
The other answers are excellent, but if you need to force a class
constructor to run without having a reference to the type (ie.
reflection), you can use:
Type type = ...;
System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor(type.TypeHandle);
I had to add this code to my application to work around a possible bug in the .net 4.0 CLR.
For anyone finding this thread and wondering... I just did the test. It appears System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor() will only run the static constructor if it has not already been run for another reason.
For example, if your code isn't positive whether or not previous code may have accessed the class and triggered the static constructor to run, it doesn't matter. That previous access will have triggered the static constructor to run, but then RunClassConstructor() will not run it also. RunClassConstructor() only runs the static constructor if it hasn't already been run.
Accessing the class after RunClassConstructor() also does not result in the static constructor being run a second time.
This is based on testing in a Win10 UWP app.
Just add public static void Initialize() { } method to your static class and call it when you want. This is very similar to call constructor, because static constructor will be called automatically.
If you have a static member in your class (there must be, otherwise static constructor wouldn't do too much) then no need to explicitly call the static constructor.
Simply access the class where you would like to call its static constructor.
E.g.:
public void MainMethod()
{
// Here you would like to call the static constructor
// The first access to the class forces the static constructor to be called.
object temp1 = MyStaticClass.AnyField;
// or
object temp2 = MyClass.AnyStaticField;
}
I have a class with a static constructor which I use to read the app.config values. How do I unit test the class with different configuration values. I'm thinking of running each test in different app domain so I can have static constructor executed for each test - but I have two problems here:
1. I do not know how to run each test run in separate app domain and
2. how do I change configuration settings at run time?
Can someone please help me with this? Or anyone has a better solution? Thanks.
Personally I would just stick your static constructor into a static method then execute that method in the static block.
You don't need to test .Net being able to load data from config files.
Instead, try to concentrate on testing your own logic.
Change your class so that it gets the configuration values from its constructor (or via properties), and then test it as you would with any other dependency.
Along the way you have also moved your class towards SRP.
As per the configuration loading - concentrate this logic in a separate, non-static class.
EDIT:
Separate the configuration logic into another class. something like this:
public static class ConfigurationLoader
{
static ConfigurationLoader()
{
// Dependency1 = LoadFromConfiguration();
// Dependency2 = LoadFromConfiguration();
}
public static int Dependency1 { get; private set; }
public static string Dependency2 { get; private set; }
}
Then, when you instantiate your class, inject it with the dependencies:
public class MyClass
{
private readonly int m_Dependency1;
private readonly string m_Dependency2;
public MyClass(int dependency1, string dependency2)
{
m_Dependency1 = dependency1;
m_Dependency2 = dependency2;
}
public char MethodUnderTest()
{
if (m_Dependency1 > 42)
{
return m_Dependency2[0];
}
return ' ';
}
}
public class MyClassTests
{
[Fact]
public void MethodUnderTest_dependency1is43AndDependency2isTest_ReturnsT()
{
var underTest = new MyClass(43, "Test");
var result = underTest.MethodUnderTest();
Assert.Equal('T', result);
}
}
...
var myClass = new MyClass(ConfigurationLoader.Dependency1, ConfigurationLoader.Dependency2);
You could go on and use IOC containers, but your problem of testing MyClass with different inputs is solved by this simple testable design.
If you read from (Web)ConfigurationManager.AppSettings, that is just a NameValueCollection, so you can replace your code that reads ConfigurationManager.AppSettings directly with code, that reads from any NameValueCollection.
Just move out your actual configuration parsing to a static method from the static ctor. Static ctor calls that static method and passes ConfigurationManager.AppSettings, but you can call that parser method from the test code, and verify the config parsing without actually touching a file, or messing with appdomains.
But on the long run, really inject your configuration parameters as seldary suggested. Create a configuration class, read the actual values at application start, and set up your IoC container to supply the same configuration instance to all requesters.
This makes further testing easier too, because you classes don't read from a global static configuration instance. You can just pass in a specific configuration instance for differet tests. Of course create a factory method for your tests, to construct a global configuration, so you don't have to do it manually all the time...
I had the same exact problem recently. The only difference was that the configuration value was coming from database instead of app.config. I was able to resolve it using TypeInitializer.
[Test]
public void TestConfigurationInStaticConstructor()
{
// setup configuraton to test
// ...
// init static constructor
ReaderTypeInit();
// Assert configuration effect
// ...
// reset static ctor to prevent other existing tests (that may depend on original static ctor) fail
ReaderTypeInit();
}
// helper method
private void ReaderTypeInit()
{
typeof(< your class with static ctor>).TypeInitializer.Invoke(null, new object[0]);
}
I have a Sealed class in C#, which already exists and all methods are static.
It does some file operations with xml file. The file name till today was hardcoded into source.
Now the requirement needs to keep it in Configuration file.
The problem is:
Since class is extract, i need to expose some static 'Initialize' method to assign filename to some local static filename variable, which will replace hardcoded string.
So, i always have to make sure, Initialize is called first and then later method.
So, the better way is to have constructor, which i cant write.
I want a better way to do this ensuring type safety.
If the filename field is static, you could make it a property or method and make sure the getter does the work of initializing it from the configuration file if it is not already initialized...
That way you don't have to explicitly initialize the class via a method you can have the access to the property itself initialize the value.
Something like below..
static string FileName { get { return (_field ?? _field = GetFileName()); } }
static string GetFileName() { /* TODO: Return filename from config */ }
Why can't you use a static constructor?
You could write a static constructor to initialize your paths before the static members are referenced.
More info can be found here
If the class itself doesn't know how to access the config I'd use a one time setter:
private static string _filename;
public static string Filename
{
get
{
if(_filename==null)
throw new InvalidOperationException("Filename not set");
return _filename;
}
set
{
if(_filename!=null)
throw new InvalidOperationException("Filename set twice");
_filename=value;
}
}
Or if the class can access the config directly it's even easier:
private static readonly string Filename;
static MyClassName()
{
Filename=GetFilenameFromConfig();
}
Just initialize it in a static constructor.
Assuming the configuration file path is known (i.e. the class takes no formal arguments), then a static constructor might help.
You could change your current class from something like:-
public static Foo
{
public static void Execute()
{
const string FileName = "foo.xml";
// ...
}
}
To something like
public static Foo
{
public static void Execute()
{
Execute("foo.xml");
}
public static void Execute(string fileName)
{
// ...
}
}
Current clients of the code can continue to use the original method (hard coded file name) and any new clients which have the file name as a configuration item can use the new method which takes the file name as a parameter. Or, if you have decided that all client should use the new method, then you can change them to do that and remove the old method.
The simplest option would be to add a static constructor. That will be executed before any other code:
public static class Foo
{
static Foo()
{
// Initialization code
}
// Other methods which can depend on initialization code having run
}
As I say, this is the simplest - in terms of changes to your existing code. However, code like this tends to be hard to debug, and if you have a lot of static constructors which depend on each other, you can get into some tricky situations (particularly if you have cyclic dependencies). For an example of this, watch the "C# Puzzlers" video from NDC 2010 - an excellent talk given by Eric Lippert and Neal Gafter.
I have a re-occurring design problem with certain classes which require one-off initialization with a parameter such as the name of an external resource such as a config file.
For example, I have a corelib project which provides application-wide logging, configuration and general helper methods. This object could use a static constructor to initialize itself but it need access to a config file which it can't find itself.
I can see a couple of solutions, but both of these don't seem quite right:
1) Use a constructor with a parameter. But then each object which requires corelib functionality should also know the name of the config file, so this has to be passed around the application. Also if I implemented corelib as a singleton I would also have to pass the config file as a parameter to the GetInstance method, which I believe is also not right.
2) Create a static property or method to pass through the config file or other external parameter.
I have sort of used the latter method and created a Load method which initializes an inner class which it passes through the config file in the constructor. Then this inner class is exposed through a public property MyCoreLib.
public static class CoreLib
{
private static MyCoreLib myCoreLib;
public static void Load(string configFile)
{
myCoreLib = new MyCoreLib(configFile);
}
public static MyCoreLib MyCoreLib
{
get { return myCoreLib; }
}
public class MyCoreLib
{
private string configFile;
public MyCoreLib(string configFile)
{
this.configFile = configFile;
}
public void DoSomething()
{
}
}
}
I'm still not happy though. The inner class is not initialized until you call the load method, so that needs to be considered anywhere the MyCoreLib is accessed. Also there is nothing to stop someone calling the load method again.
Any other patterns or ideas how to accomplish this?
You need a common location to store this. You could use the app.config even if this is a seperate assembly by defining a config section in the library assembly and referencing it you proceess app.config. Or you could just add a generic setting to appSettings and reference that without using strongly typed settings. If the value is user entered then you could use isolated storage.
Finally you could put it in a well known location in the registry at install time.
For code the following is encapsulted better
public interface ICoreLib
{
void SomeMethod();
}
public static class CoreLibManager
{
private static ICoreLib coreLib;
private static volatile bool initialized;
private static readonly object lockObject = new object();
public static ICoreLib CoreLib
{
get
{
Inititialize();
return coreLib;
}
}
/// <summary>
/// The inititialize.
/// </summary>
private static void Inititialize()
{
if (initialized)
{
lock (lockObject)
{
if (!initialized)
{
string configFile = // Fech from common location
coreLib = new MyCoreLib(configFile);
initialized = true;
}
}
}
}
/// <summary>
/// The my core lib.
/// </summary>
private class MyCoreLib : ICoreLib
{
public MyCoreLib(string configPath)
{
}
public void SomeMethod()
{
}
}
}
When you have global state like this that you need to initialize and it requires outside input to complete initialization (such as a config file), then you're stuck with the outside code that knows about the input having to call Load or Initialize to initialize your global state. There's no way around this.
The issue that you've correctly observed, however, is that anybody could try to use the global state before it has been properly Initialized, which is the downside to having it exposed in this way. The way you get around this is by refactoring all of the stateful parts of your global library into an instance class and passing references to that instance through your application. Because you control when it is created and initialized, you can now ensure it has valid state before you pass it along. You trade off the convenience of global state for the better insulation you're after.
You can use the .net configuration system to do this. The simplest way to do this is to use the <appsettings> element in your web.config file, or in your appname.exe.config file. Use:
ConfigurationManager.AppSettings["property_name"]
to access a property. Whether your code is running in a web context or as a windows app, the configuration system will find the config file and load the values you need.
You can also build a more complex system with type-safe config values and hierarchical data, but my needs were pretty simple, so I didn't explore this after the first headache set in :)
You could make the class a singleton, thus ensuring there's only ever one instance of it while also allowing for the constructor parameter.
There won't be much alternatives.
Either you pass stuff around (in that case I'd not pass the string around but create a concrete (non-static) CoreLib and pass that around or you do what you suggested.
Don't forget to hide the constructor for MyCoreLib. Currently it is public which is likely unintended.
OK, thanks everyone for your assistance. I've refactored the CoreLib project and broken out the config handling into a separate project. Now we have a solution-wide shared class for config management. The class can take care of itself with a user setting, which is exposed via the static property ConfigFile. This property also persists the modified file location if the user changes via some config dialog. Also the initialized flag will be reset if the config file changes.
public interface IConfig
{
void SomeMethod();
}
public static class ConfigurationManager
{
private static IConfig config;
private static volatile bool initialized;
private static readonly object lockObject = new object();
public static string ConfigFile
{
get { return Properties.Settings.Default.ConfigFile; }
set
{
if (Properties.Settings.Default.ConfigFile == value) return;
lock (lockObject)
{
Properties.Settings.Default.Save();
initialized = false;
}
}
}
public static IConfig Config
{
get
{
Inititialize();
return config;
}
}
private static void Inititialize()
{
lock (lockObject)
{
if (initialized) return;
config = new Configuration(Properties.Settings.Default.ConfigFile);
initialized = true;
}
}
}
internal class Configuration : IConfig
{
public ClientConfig(string configFile)
{
// Parse & validate config file
}
public void SomeMethod()
{
}
}
So now in the start-up we first validate the persisted ConfigFile setting, then attempt to access the Configuration instance via the manager's Config property. Any parsing exceptions can be handled here and dealt with accordingly. Then it is up to the developer to handle any exceptions for IConfig's methods.
if (!System.IO.File.Exists(ConfigurationManager.ConfigFile))
{
// Display config file locator dialog
ConfigurationManager.ConfigFile = someDialog.FileName;
}
try
{
IConfig config = ConfigurationManager.Config;
}
catch
{
// Error parsing config file
}