C# 在执行期间动态覆盖WebConfiguration Manager.AppSettings[“SomeProperty”]
我有这样一个代码:C# 在执行期间动态覆盖WebConfiguration Manager.AppSettings[“SomeProperty”],c#,asp.net,web-config,overriding,C#,Asp.net,Web Config,Overriding,我有这样一个代码: // can't make any changes at that class class MyClass { void SomeMethod() { // some code ... var someVar = WebConfigurationManager.AppSettings["SomeProperty"]; // some code ... } } 我无法更改该代码,但我需要WebConf
// can't make any changes at that class
class MyClass
{
void SomeMethod()
{
// some code ...
var someVar = WebConfigurationManager.AppSettings["SomeProperty"];
// some code ...
}
}
我无法更改该代码,但我需要WebConfiguration Manager.AppSettings[SomeProperty]根据某些外部条件(例如,根据用户角色)返回不同的值。所以我正在寻找某种方法来覆盖对该属性的访问。在该重写方法中,我将检查用户角色和
返回适当的值
有办法吗
我发现了这个问题:但它似乎不适合我,因为这里WebConfiguration Manager.AppSettings[SomeProperty]的值在应用程序启动时设置一次。而且我需要动态地进行更改。如果您直接更改Web.config,它们将仅在下一个请求期间有效,而且据我所知,这不是期望的效果 您不能直接影响WebConfiguration Manager.AppSettings[SomeProperty],这是所需的行为,因为AppSettings as配置是静态的 为了达到接近您期望的效果,我建议您使用HttpContext.Current.Items集合,在该集合中,如果满足条件,您将在应用程序_BeginRequest中初始化为特定值,否则默认为WebConfiguration Manager.AppSettings[SomeProperty]。
然后,您将访问HttpContext.Current.Items[SomeProperty],而不是访问WebConfiguration Manager.AppSettings[SomeProperty]。从web.config检索值后,您似乎需要执行一些逻辑。如果该逻辑修改了该值本身,则可以在web.config中存储格式字符串 下面是一个使用连接字符串设置的示例。我正在使用格式字符串在运行时填充服务器名称:
<add name="sqlconnection" connectionString="Server={0}\SQLEXPRESS;Database=xxx;Trusted_Connection=True;"/>
<>编辑:如果不能直接编辑类,我会考虑创建一个部分类来实现这一点。如果你不能改变正在读取AppSt设置的代码,那么就没有办法做你想做的事情。WebConfiguration Manager不可从外部插拔或重播 您必须更改代码。不,当然不能
如果你不能改变类,那么你就不能改变行为。微软在WebApplicationManager中设置覆盖功能并没有一般原因。通常,人们希望能够更改一个类,或者正确地设计它,以便以正确的方式覆盖它。在MVC中,为了简化测试和模拟,我倾向于为所有通过接口引用的公共类(如Request、Session和ConfigManager)使用自定义对象。 基本上不需要从头开始实现类,所以您的实现可以是一个包装器,它实际上在引擎盖下使用.NET类,但是它也有机会在中间插入一些自定义逻辑,就像在您的例子中一样。 因此,您可以使用包含您自己的逻辑的方法(如GetAppConfigkey)创建WebConfiguration Manager的包装器。 因此,使用依赖注入的概念很容易,只要您需要,这个类就可以在任何地方使用 因此,举一个简单的例子:
//this will be injected
public MyControllerCtor(IConfig cfg)
public interface IConfig
{
string GetAppConfig(string key);
}
public class myConfig:IConfig
{
public string GetAppConfig(string key)
{
//your logic
var someVar = WebConfigurationManager.AppSettings["SomeProperty"];
//your logic
return yourCustomAppSetting;
}
}
这种方法的最大优点是,如果您想将配置存储在数据库或服务中,并更改代码,只需更改接口实现并注入新实例。谢谢您的回复。但问题是我已经有了使用WebConfiguration Manager.AppSettings[SomeProperty]的代码,我无法更改它。因此,我需要以某种方式捕获对WebConfiguration Manager.AppSettings[SomeProperty]的所有调用,并覆盖它们。恐怕这不可能。找到并替换将是你最好的朋友。。。对于将来,将这样的行为封装到函数中总是很好的,这样每当您进行更改时,您只需在一个地方进行更改。谢谢您的回复。这是一个有趣的解决方案,我会记下来的。但在这种情况下,它不适合我,因为我有一个类和方法在其中,它包含代码,我不能在那个类中更改任何东西。但再次感谢。这并不意味着他不能在其他地方使用。添加了一个建议,可能有助于你避开不能直接编辑类的事实。
//this will be injected
public MyControllerCtor(IConfig cfg)
public interface IConfig
{
string GetAppConfig(string key);
}
public class myConfig:IConfig
{
public string GetAppConfig(string key)
{
//your logic
var someVar = WebConfigurationManager.AppSettings["SomeProperty"];
//your logic
return yourCustomAppSetting;
}
}