I have a base class that contains the basic logic to perform an http request. However I need to have some kind of switch because dependending on the configuration set by the user, the domain of the url will change.
Based on that I created a static property that holds an enum responsible to give me the base value I need. On top of that, the base class will be distribuited via nuget package, so it is somewhat sealed to the users, that need only to implement its required fields and can use any logic defined on its parent.
So basically I came up with this solution so far.
public abstract class Base{
protected static Environment Environment { get; set; }
public static Init(Environment NewEnvironment){
Environment = NewEnvironment;
}
public void UseEnvironment(){
//use the selected environment on the method
}
}
public A : Base{
public void UseAEnvironment(){
UseEnvironment(); //using the environment defined with A.init() call
}
}
public B : Base{
public void UseBEnvironment(){
UseEnvironment(); //using the environment defined with B.init() call
}
I know that there is only one copy of the static property in memory, thus when you set it to a value for the A class, B will end up using the same value.
I need to be able to do
A.Init(Environment.Debug);
B.Init(Environment.Release);
So when I run the program, all methods defined in class A will run with the Debug value, while class B will have the Release value.
My solution does not do what I need, is there a way to make it work, or is there any better architecture decisions to avoid this situation and accomplish a similar result?
If you have:
public abstract class Base<T> where T : Base<T>
{
protected static Environment Environment { get; private set; }
public static void Init(Environment newEnvironment)
{
Environment = newEnvironment;
}
}
And then:
public class A : Base<A>
{
...
}
public class B : Base<B>
{
...
}
then you can just do:
Base<A>.Init(Environment.Debug);
Base<B>.Init(Environment.Release);
It works because each substitution of something for T
in Base<T>
has its own static members. That is, each constructed generic type ("closed" generic type) has separate static fields.
You could also write it as:
A.Init(Environment.Debug);
B.Init(Environment.Debug);
but I would consider that slightly confusing, even if it is a more compact syntax.