How do I ensure that the Factory class' properties get initialized after Application_Start?
public static class Globals
{
public Static Customer Cust {get;set;}
}
public class WebApiApplication : HttpApplication
{
protected void Application_Start()
{
Globals.Cust = GetCustomerFromDataBase();
}
}
public static class Factory
{
public static Customer Cust => Globals.Cust ;
}
The Factory.Customer gets called by a method inside a webapi controller.
The answer to your question depends on your code. If as you say, Factory.Cust is first referenced in a WebAPI Controller method, then you should be safe; the Application_Start method should have run before anything in one of your controllers.
Your Factory.Cust property doesn't get initialized. When someone tries to read the value of Factory.Cust, all that happens is that the Globals.Cust property (getter) is executed (remember, properties are really code, not just state). As long as Globals.Cust is initialized before Factory.Cust is read, you are safe. If you test your code (by putting breakpoints here and there) and it seems to follow what I'm saying, you should be OK.
What I was saying in the comments about static classes is that a static class can have a constructor. It can be explicit (you write a constructor for the class), but it can also have other code you have in your class. For example, if, in your Factory class, you had code that looked like:
private static Customer _localCustomerStuff = new Customer();
Then the code that's associated with that field would be folded into the Factory constructor. Property initializers like the one below also do the same kind of thing (since they are initializing the hidden backing store for the property).
public static string SomeString { get; set; } = "SomeString Initial Value";
You don't know exactly when a static class's constructor code will run, but there is a guarantee made by the framework that it will run before any reference to that class is made. If you access the Factory class, and you had some initialization associated with that class (none of which you show in your post above), then you can be sure that the initialization will have started before you access anything to do with the class.
Take a look at Static Constructor Docs to see what I'm talking about.
Related
I have an abstract base class, and subclasses who all have an automatically generated Instance static field of their own type, done through using genericity "in between" the base and sub classes (see code below).
When those instances are created, I register them in a dictionary based on specific "identifying" fields overwritten in subclass constructors, in order to access them somewhere else in the code.
I could register them in their constructors, however I don't want to have to drag and copy/paste this same bit of code in every such subclass in order to register them.
public abstract class BaseClass
{
// Declaration of fields and methods
}
public class GenericBaseClass<T> : BaseClass where T : GenericBaseClass<T>
{
private static T instance = ((T) Activator.CreateInstance(typeof(T), true)).Register();
public static T Instance => instance;
public T Register()
{
// Registers Instance in a dictionary.
}
}
public class Subclass1 : GenericBaseClass<Subclass1>
{
private Subclass1()
{
// Modification of protected fields.
}
}
Doing this enables me to call Subclass1.Instance, and by doing so, this instance gets registered in my dictionary, however it doesn't get registered before I try to access it, and only Subclass1 gets that treatment, not other subclasses.
I followed this answer https://stackoverflow.com/a/34726769/13738641 (in the updated section) and made a static constructor for BaseClass and for GenericBaseClass hoping it would initialize static fields for those subclasses, to no avail.
It appears from debugging that the BaseClass static constructor is indeed called, and it does fetch the right subclasses, but it doesn't throw an error, nor does it calls the subclass (static) constructors. Now I could be going crazy, but I could have sworn it worked once before I tried modifying something before reverting back to that, only for it not to work anymore.
I've tried adding a static constructor to the generic class which I hoped would be called once for each subclass, but this constructor only gets called once (when I access some subclass's instance in order to trigger the BaseClass static constructor call).
Any suggestion on what to do to achieve this? I accept suggestion on other ways to achieve something similar (i.e. keep a dictionary generated at runtime with instances of my classes), the subclasses being singletons isn't critical, so maybe I could register constructors instead of instances in the dictionary? I have no idea if that is even possible, with each constructor returning a different type.
You could loop through the types in your assembly and check if they implement the generic class, and then invoke the static constructor of the generic class (which will implicitly invoke the static constructor of the sub class because of Activator.CreateInstance) by calling RuntimeHelpers.RunClassConstructor. So just add a method that does that can call it:
public static void RegisterAll()
{
foreach(var type in typeof(BaseClass).Assembly.GetTypes().Where(t => t.BaseType.IsGenericType &&
t.GetGenericTypeDefinition() == typeof(GenericBaseClass<>)))
{
RuntimeHelpers.RunClassConstructor(type.BaseType.TypeHandle);
}
}
I have a class defined as:
public class DatabaseEntity<T> where T : DatabaseEntity<T> {
public static string Query { get; protected set; }
public static IList<T> Load() {
return Database.Get(Query);
}
}
public class Node : DatabaseEntity<Node> {
static Node() {
Node.Query = #"SELECT Id FROM Node";
}
}
When I run Node.Load() from a codebehind (Window.xaml.cs) the Node's static constructor never fires; or at least doesn't hit a breakpoint and does not set Node.Query to anything other than null.
Is there any reason why this might occur?
Solution
Check out the answers below for a few solutions. For my case, I decided to simply make the Query variable public, and set all instances of Query in one place. (Not ideal, but it works.)
The problem lies in your assumptions about when a static constructor is called. The documentation, which isn't the clearest, states that
It is called automatically before the first instance is created or any static members are referenced.
You may assume that if you call
Node.Load();
that you are calling a static method on the Node class, but in fact you're calling it on the base class, as that is where it is implemented.
So, to fix this, you have two choices. First, you can trigger the static constructor explicitly by creating a new instance of the Node class prior to calling Load()
var foo = new Node(); // static ctor triggered
Node.Load();
or create a protected virtual member that the base class can call in order to get the query value (can't use abstract here, unfortunately)
public class DatabaseEntity<T> where T : Derp {
protected abstract string Query { get; }
public static IList<T> Load() {
return Database.Get(new DatabaseEntity<T>().Query);
}
}
Both of which are hacky. Better to dispense with the statics altogether and go with instance methods. Statics should be used sparingly, as they result in tight coupling and other design headaches such as this.
Yes, static constructors will not be called till the members of the class is first accessed or first instance is created.
In your case you're accessing DatabaseEntity<T>.Load, so static constructor of DatabaseEntity<T> will be called not its derived class ones.
Even though you call Node.Load it is mapped to DatabaseEntity<Node> at compile time. So technically you're not accessing Node class at all.
You can also call class constructors directly using System.Runtime.CompilerServices and the RuntimeHelpers type by doing something as follows:
RuntimeHelpers.RunClassConstructor(type.TypeHandle);
So for example you could use reflection to loop over all types in an inheritance chain and call each of the static constructors.
An example is worth a thousand stupid questions so:
public class OuterClass
{
public static class InnerClassEventArgs : EventArgs
{
public static int SomeInt;
}
}
and in a galaxy far far away:
public void SomeFunkyFunc()
{
OuterClass Instance1;
OuterClass Instance2;
Instance1.InnerClassEventArgs.SomeInt = 1;
Instance2.InnerClassEventArgs.SomeInt = 2;
//WHAT WOULD Instance1.InnerClassEventArgs.Someint == ?
}
Yes, I realize now that I've typed this that I've almost coded all I need to answer my own question. I'd rather not create a new project and go through the trouble if someone smarter than me knows off the top of their head.
Instance1.InnerClassEventArgs.SomeInt would equal 2. Static fields are shared across all instances of the class -- or as MSDN puts it:
The static member is always accessed by the class name, not the instance name. Only one copy of a static member exists, regardless of how many instances of the class are created.
Note that your specific example won't compile -- you'll get an error message that says "Cannot access static class 'InnerClassEventArgs' in a non-static context."
You'd have to use the following code instead, which hopefully makes the behavior more understandable:
OuterClass.InnerClassEventArgs.SomeInt = 1;
OuterClass.InnerClassEventArgs.SomeInt = 2;
A static class has exactly one instance, "shared" by all its usages (in your case, all instances of OuterClass). Therefore, the state of that object will be the sum of all changes made by any usage. In this simple example, SomeInt will be 2, regardless of which OuterClass instance you used to access it again (Instance1 or Instance2).
I'm conveniently ignoring all of the following:
A static class cannot inherit from any other class. InnerClassEventArgs thus cannot inherit from EventArgs.
Instance1 and Instance2 are not initialized; this will cause its own compile-time error if you use ReSharper ("X may not be initialized before accessing").
Static members (including nested static classes) cannot be accessed based on any one instance; you would access InnerClassEventArgs in static context.
I heard that a private constructor prevents object creation from the outside world.
When I have a code
public class Product
{
public string Name { get;set;}
public double Price {get;set;}
Product()
{
}
public Product(string _name,double _price)
{
}
}
Here I still can declare a public constructor (parameter), won't it spoil the purpose of the private constructor? When do we need both private and public constructor (parameter) in code?
I need a detailed explanation please.
The reason you would use the pattern you're describing is when you want to control how the object is instantiated.
In your example, for instance, you're saying the only way to create a Product is by specifying its name and price. This is with respect to the outside world, of course. You could also do something similar using other access modifiers, and it would have different implications, but it all boils down to controlling how you want the objects instantiated with respect to who will be doing it.
If you wanted to prevent object creation altogether you would have to make all your constructors private (or protected). That would force the object to be created from within itself (or an inherited class).
Also, as Matti pointed out in the comment below, when you define a constructor that is parameterized you don't need to specify a private default constructor. At that point it is implied.
Constructors can be chained together to avoid having to duplicate code. It is quite common to have private constructors, that nobody is supposed to call outside of the class, that are chained from a public constructor.
Example:
public class Test
{
private Test(int? a,string b) { }
public Test(int a) : this(a, null) { }
public Test(string b) : this(null, b) { }
}
Here there are two public constructors, one taking a string and one taking an int. They both chain to the common private constructor that takes both arguments.
Also, you can construct new objects from within the same class by using the private constructor. For instance, when you want specialized constructors only available through static factory methods:
public static Test Create()
{
int? a = ReadConfigurationForA();
string b = ReadConfigurationForB();
return new Test(a, b);
}
When it is not be a good idea to expose a private constructor to the outside world, add a static factory method that fetches the correct arguments to pass on the constructor.
You need a private constructor when you only want that constructor to be called from within the class itself. In your example you are forcing the calling object to provide 2 parameters when creating the object.
With a private constructor you could do something like:
public static GetInstance ()
{
return new YourObject();
}
but nothing else except the object could call the parameterless constructor.
It's commonly used to create a singleton pattern:
http://www.dofactory.com/Patterns/PatternSingleton.aspx
You would use a constructor with parameters when you wanted to force calling code to pass a value to the constructor in order to create an instance of your class. In your example, calling code must use the parameter version of the constructor in order to create a Product.
A private constructor is a special instance constructor. It is commonly used in classes that contain static members only. If a class has one or more private constructors and no public constructors, then other classes (except nested classes) are not allowed to create instances of this class.
For more details refer to this:
http://msdn.microsoft.com/en-us/library/kcfb85a6(VS.80).aspx
Please, help me with to understand this piece of code:
protected Customer()
{
}
in the following class (Model class from sample WPF MVVM app):
public class Customer : IDataErrorInfo
{
#region Creation
public static Customer CreateNewCustomer()
{
return new Customer();
}
public static Customer CreateCustomer(
double totalSales,
string firstName,
string lastName,
bool isCompany,
string email)
{
return new Customer
{
TotalSales = totalSales,
FirstName = firstName,
LastName = lastName,
IsCompany = isCompany,
Email = email
};
}
protected Customer() // it is what I asked about
{
}
#endregion // Creation
......
}
protected Customer() { } is a constructor, a special method that automatically gets called when you instantiate an object from a class. When you type Customer c = new Customer(), the constructor is allowed to initialize that instance after the run-time has allocated and reset memory for it. The protected keyword means that only code inside the class Customer or of its descendants are allowed to instantiate said class using that specific constructor.
The piece of code you point at is a constructor. It is a method that (potentially) gets automatically invoked whenever an instance of your class is created at runtime.
In this case, it is marked with the protected keyword. This means that only the owner class plus any derived classes (i.e. classes that inherit from it) have access to it.
By looking at your code, the two versions of the CreateNewCustomer() static method in your class create instances of the class, invoking the constuctor. By making the constructor protected, the code guarantees that the class retains exclusive control over instantiation; this means that no other code outside the class (or its descendant classes) can create instances of this class.
The constructor is protected so that only the static creation methods can actually instantiate the class.
This means that the constructor for your class has "protected" access, meaning that only members of this class or subclasses can call it. Practically, this means that either a static method is being used to create an instance of this class, or that another constructor (possibly in a derived class) is delegating to this constructor.
Using the protected keyword on the constructor only allows instantiation of the Customer object inside itself (like the static factory methods) and inside any class that derives from Customer.