我想我已经超越了自己。您不能用配置替换代码,因为代码会做某事,而配置只会告诉代码做什么或如何做某事(除非配置本身包含代码,在这种情况下您会遇到悖论)。如果您想将可配置性应用于您的代码,您首先需要使其更通用/通用(您的switch
陈述表明它现在不通用)。我的原始答案(如下)中描述了我这样做的方法。它本身不提供可配置性,但可以这样做(我做得很简单)。该代码基于您的原始问题,因此请重新调整您的眼睛以正确阅读。
我过去选择的选项是使用工厂(无论是安装在单例中还是以 IoC 容器的形式传递给拥有您的代码示例的函数。
我的方法的非常高级的实现基本上是定义一个自定义属性,该属性包含一个指示您的类型何时有用的属性。就像是:
public class DbOperationAttribute : Attribute
{
public string Operation { get; set; }
}
以及提供运行代码所需的 API 的通用接口。就像是:
public interface IDoSomethingSpecial
{
bool Execute(SomeExecutionContext context);
}
然后用属性装饰特定的类并实现接口以指示它们适用于每个操作:
[DbOperation(Operation = "Read")]
public class DBReadOperation : IDoSomethingUseful
{
// Our implementation of the `IDoSomethingUseful` interface
public bool Execute(SomeExecutionContext context)
{
// Do something useful in here
}
}
在您的程序中的某个时刻,您需要能够发现哪些类型适合哪些操作。我通过反射来做到这一点,尽管它可以通过配置轻松完成(这会破坏属性的点)。几个 IoC 容器提供了类似的可发现性属性,尽管使用其他人的容器,您将按照他们的方式(通常)做事。
一旦你发现了哪些类型适合哪些操作,你可以使用类似的东西:
IDoSomethingUseful someAction = myCollectionOfUsefulThings(requesttype);
someAction.Execute(someInstanceOfOurContextType);
基于这种设计,我倾向于只使用App.Config
/Web.Config
来存储您的配置。无论如何,它通常会在那里;也可以将其用于您的目的。