在执行期间动态覆盖WebConfigurationManager.AppSettings [“SomeProperty”]

时间:2011-10-27 09:35:32

标签: c# asp.net web-config override

我有这样的代码:

// can't make any changes at that class
class MyClass
{
    void SomeMethod()
    {
        // some code ...

        var someVar = WebConfigurationManager.AppSettings["SomeProperty"];

        // some code ...
    }
}

我无法更改该代码,但我需要WebConfigurationManager.AppSettings [“SomeProperty”]根据某些外部条件(例如,取决于用户角色)返回不同的值。所以我正在寻找一些方法来覆盖对该属性的访问。在该覆盖方法中,我将检查用户角色和 返回适当的值。

有没有办法做到这一点?

我发现了这个问题:Is there a way to override ConfigurationManager.AppSettings?但它似乎不适合我,因为WebConfigurationManager.AppSettings [“SomeProperty”]的值在应用程序启动时设置了一次。我需要动态地完成它。

5 个答案:

答案 0 :(得分:1)

在MVC中,为了简化测试和模拟,我倾向于为所有常见类使用自定义对象,例如通过接口引用的Request,Session和ConfigManager。 你基本上不需要从头开始实现类,所以你的实现可以是一个实际上使用.net类的包装器,但它也有机会在中间插入一些自定义逻辑,比如你的情况下。

因此,您可以使用包含您自己的逻辑的GetAppConfig(key)方法创建webconfigurationManager的包装器。 使用依赖注入的概念就足够了,可以在任何需要的地方使用该类。

因此,举一个简单的例子:

//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;
   }
}

这种方法的一大优势是,如果您希望将配置存储在数据库或服务中,并更改代码,则只需更改接口实现并注入新实例。

答案 1 :(得分:0)

听起来你需要在从web.config中检索值后做一些逻辑。如果逻辑修改了值本身,则可以始终在web.config中存储格式字符串。

以下是使用连接字符串设置的示例。我正在使用格式字符串在运行时填充服务器名称:

<add name="sqlconnection" connectionString="Server={0}\SQLEXPRESS;Database=xxx;Trusted_Connection=True;"/>    

然后我正在使用这个逻辑:

string connect = ConfigurationManager.ConnectionStrings["sqlconnection"].ConnectionString;
if (!String.IsNullOrEmpty(connect))
{
    //check to see if the connection string needs to be set at runtime
    if (connect.Contains("{0}"))
        connect = String.Format(connect, HttpContext.Current.Server.MachineName);
}

return connect;

编辑:如果您无法直接编辑该类,我会考虑创建一个部分类来实现它。

答案 2 :(得分:0)

如果您无法更改正在阅读AppSettings的代码,则无法执行您想要的操作。 WebConfigurationManager不可插拔或外部可替换。

您必须更改代码。

答案 3 :(得分:0)

不,当然不是。

如果您无法更改班级,则无法更改行为。微软没有在WebApplicationManager中放置“覆盖”功能的一般原因。通常,人们期望能够改变一个类,或者正确设计它,以便能够以正确的方式覆盖它。

答案 4 :(得分:-1)

如果您对Web.config进行直接更改,它们将仅在下一次请求期间生效,据我所知,这不是预期的效果。

您不能直接影响WebConfigurationManager.AppSettings [“SomeProperty”],这是所需的行为,因为AppSettings作为配置是静态的。

为了达到你想要的效果,我建议你使用HttpContext.Current.Items集合,如果满足条件,你将在Application_BeginRequest中初始化为某个值,或默认为WebConfigurationManager.AppSettings [否则“SomeProperty” 而不是访问WebConfigurationManager.AppSettings [“SomeProperty”],而不是访问HttpContext.Current.Items [“SomeProperty”]。