我有一个基类,它包含执行http请求的基本逻辑。但是我需要进行某种切换,因为依赖于用户设置的配置,url的域名将会改变。
基于此我创建了一个静态属性,其中包含一个负责给出我需要的基值的枚举。最重要的是,基类将通过nuget包进行分配,因此它对用户来说有点密封,只需要实现其必需的字段,并且可以使用在其父级上定义的任何逻辑。
所以基本上我到目前为止都想出了这个解决方案。
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
}
我知道内存中只有一个静态属性的副本,因此当你将它设置为A类的值时,B最终会使用相同的值。
我需要能够做到
A.Init(Environment.Debug);
B.Init(Environment.Release);
因此,当我运行程序时,A类中定义的所有方法都将使用Debug值运行,而B类将具有Release值。
我的解决方案不能满足我的需求,有没有办法让它工作,或者是否有更好的架构决策来避免这种情况并取得类似的结果?
答案 0 :(得分:2)
如果你有:
public class A : Base<A>
{
...
}
public class B : Base<B>
{
...
}
然后:
Base<A>.Init(Environment.Debug);
Base<B>.Init(Environment.Release);
那么你可以这样做:
T
这很有效,因为Base<T>
中A.Init(Environment.Debug);
B.Init(Environment.Debug);
的某些内容替换都有自己的静态成员。也就是说,每个构造的泛型类型(“封闭”泛型类型)都有单独的静态字段。
你也可以把它写成:
spark.executorEnv.PYTHON_EGG_CACHE="./.python-eggs/"
spark.executorEnv.PYTHON_EGG_DIR="./.python-eggs/"
spark.driverEnv.PYTHON_EGG_CACHE="./.python-eggs/"
spark.driverEnv.PYTHON_EGG_DIR="./.python-eggs/"
但我认为这有点令人困惑,即使它是一种更紧凑的语法。
答案 1 :(得分:1)
这似乎有点奇怪的设计。也许类似于编译器指令(#if DEBUG)或通过App.config或类似配置更合适?
无论如何,如果不是......以下内容应该有效
public abstract class Base<T> where T : Base<T>
{
private static readonly IDictionary<Type, Environment> _Environments = new Dictionary<Type, Environment>();
public static void Init(Environment NewEnvironment)
{
_Environments[typeof(T)] = NewEnvironment;
}
protected Environment GetEnvironment()
{
if (!_Environments.ContainsKey(typeof(T)))
return default(Environment);
return _Environments[typeof(T)];
}
}
public class A : Base<A> {
// ...
}
public class B : Base<B> {
// ...
}
答案 2 :(得分:0)
我不喜欢以下提议的代码,但它代表了提供我认为您尝试做的最少量的代码剧变。请注意在抽象基类中删除静态声明。
public abstract class Base {
protected Environment Environment { get; set; }
public Init(Environment NewEnvironment) {
Environment = NewEnvironment;
}
}
public A : Base{
public void UseEnvironment() {
}
}
public B : Base{
public void UseEnvironment() {
}
}
然后初始化。
static A DebugHttpAccess;
static B RealeaseHttpAccess;
DebugHttpAccess = new A();
DebugHttpAccess.Init(Environment.Debug);
RealeaseHttpAccess= new B();
RealeaseHttpAccess.Init(Environment.Release);
最后按照其他更高级别的逻辑使用:
if ( needDebugHttpTracing )
DebugHttpAccess.UseEnvironment();
else
ReleaseHttpAccess.UseEnvironment();
我怀疑您的需求的正确解决方案涉及控制反转和一个可以将Http访问的生命周期作为单例类来管理的容器。容器将按照其他进程范围的配置设置注入适当的Http访问实例。
有关IOC容器的示例,请参阅autofac.org。