我有这样的代码:
// 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”]的值在应用程序启动时设置了一次。我需要动态地完成它。
答案 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”]。