2015-05-13 19 views
6

Linqpad là kịch bản duy nhất giống như môi trường nơi tôi có thể làm việc với cơ sở mã lớn của mình. Lý do nó là môi trường duy nhất làm việc cho tôi là các giải pháp khác (ironpython, vv) luôn không tải đúng cấu hình từ app.config, nhưng linqpad.config hoạt độngTôi có thể chỉ định tệp cấu hình linqpad theo cách lập trình không?

Vấn đề là, tôi có nhiều tệp cấu hình và mọi thời gian tôi muốn sử dụng một trong số họ cho một kịch bản, tôi phải đi đến thư mục cài đặt linqpad, đổi tên tập tin cấu hình đúng để linqpad.config và khởi động lại LINQ. Năng suất cao.

Tôi đã cố gắng để thiết lập các tập tin thông qua:

AppDomain.CurrentDomain.SetData("APP_CONFIG_FILE", @"C:\Shared\app.config"); 

nhưng nó không có hiệu lực. Có cách nào tôi có thể thay đổi tập tin cấu hình sẽ được sử dụng trong chính() phương pháp của một chương trình C# trong Linqpad? Nếu tôi có thể thực hiện cuộc gọi đến một chức năng đặt tập tin cấu hình sẽ được sử dụng và sau đó chạy phần còn lại của mã của tôi, điều đó sẽ tuyệt vời.

+0

Thay vì đổi tên tập tin cấu hình và tái khởi động LINQPad, có bạn coi là tạo riêng biệt thư mục, mỗi thư mục với một bản sao của tập tin cấu hình mong muốn và LINQPad.exe? –

+0

Điều này không thực sự cải thiện năng suất của tôi. Khi tôi muốn tạo một truy vấn mới nên sử dụng một tệp cấu hình cụ thể, bao gồm một cuộc gọi ở đầu cuộc gọi sẽ nhanh hơn rất nhiều so với việc tạo thư mục mới với exe + config vv. Đây là lý do tại sao tôi hỏi cụ thể nếu thiết lập có lập trình là có thể. – mahonya

+2

Tôi hiểu. Không thể bây giờ, nhưng trên danh sách TODO. LINQPad sẽ trong tương lai cho phép điều này thông qua tùy chọn thuộc tính truy vấn. Nó sẽ không bao giờ được lập trình có thể, mặc dù. Vào thời điểm kịch bản chạy, đã quá muộn. –

Trả lời

9

Ví dụ LINQ Query:

void Main() 
{ 
    var configPath = Path.Combine(Path.GetDirectoryName(Util.CurrentQueryPath), "app.config"); 

    // Load custom config 
    var configProxy = new ConfigurationProxy(configPath); 
    if (!configProxy.InjectToConfigurationManager()) 
    { 
     Trace.TraceError("Cannot load config from " + configPath); 
     throw new InvalidOperationException("Cannot load config " + configPath); 
    } 

    ConfigurationManager.AppSettings["LogPath"].Dump(); 
} 

Thêm lớp này để truy vấn LINQ của bạn:

/// <summary> 
/// A custom config injector. 
/// </summary> 
public sealed class ConfigurationProxy : IInternalConfigSystem 
{ 
    /// <summary> 
    /// The custom sections 
    /// </summary> 
    private readonly Dictionary<string, IConfigurationSectionHandler> customSections; 

    /// <summary> 
    /// The configuration 
    /// </summary> 
    private Configuration config; 

    /// <summary> 
    /// Initializes a new instance of the <see cref="ConfigurationProxy"/> class. 
    /// </summary> 
    /// <param name="fileName"> 
    /// Name of the file. 
    /// </param> 
    /// <remarks> 
    /// this is called filename but really it's the path as needed 
    /// it defaults to checking the directory you're running in. 
    /// </remarks> 
    public ConfigurationProxy(string fileName) 
    { 
     this.customSections = new Dictionary<string, IConfigurationSectionHandler>(); 

     if (!this.Load(fileName)) 
     { 
      throw new ConfigurationErrorsException(string.Format(CultureInfo.CurrentCulture, "File: {0} could not be found or was not a valid configuration file.", this.config.FilePath)); 
     } 
    } 

    /// <summary> 
    /// Gets the configuration. 
    /// </summary> 
    public Configuration Configuration 
    { 
     get 
     { 
      return this.config; 
     } 
    } 

    /// <summary> 
    /// Returns the configuration object based on the specified key. 
    /// </summary> 
    /// <param name="configKey">The configuration key value.</param> 
    /// <returns> 
    /// A configuration object. 
    /// </returns> 
    public object GetSection(string configKey) 
    { 
     if (configKey == "appSettings") 
     { 
      return this.BuildAppSettings(); 
     } 

     object sect = this.config.GetSection(configKey); 

     if (this.customSections.ContainsKey(configKey) && sect != null) 
     { 
      var xml = new XmlDocument(); 

      xml.LoadXml(((ConfigurationSection)sect).SectionInformation.GetRawXml()); 

      // I have no idea what I should normally be passing through in the first 
      // two params, but I never use them in my config handlers so I opted not to 
      // worry about it and just pass through something... 
      sect = this.customSections[configKey].Create(this.config, this.config.EvaluationContext, xml.FirstChild); 
     } 

     return sect; 
    } 

    /// <summary> 
    /// The refresh config. 
    /// </summary> 
    /// <param name="sectionName"> 
    /// The section name. 
    /// </param> 
    public void RefreshConfig(string sectionName) 
    { 
     // I suppose this will work. Reload the whole file? 
     this.Load(this.config.FilePath); 
    } 

    /// <summary> 
    /// Gets a value indicating whether supports user config. 
    /// </summary> 
    public bool SupportsUserConfig 
    { 
     get 
     { 
      return false; 
     } 
    } 

    /// <summary> 
    /// Injects to configuration manager. 
    /// </summary> 
    /// <returns>Whether the configuration was injected</returns> 
    public bool InjectToConfigurationManager() 
    { 
     // inject self into ConfigurationManager 
     var configSystem = typeof(ConfigurationManager).GetField("s_configSystem", BindingFlags.Static | BindingFlags.NonPublic); 
     if (configSystem != null) 
     { 
      configSystem.SetValue(null, this); 
     } 

     // lame check, but it's something 
     if (ConfigurationManager.AppSettings.Count == this.config.AppSettings.Settings.Count) 
     { 
      return true; 
     } 

     return false; 
    } 

    /// <summary> 
    /// Loads the specified file. 
    /// </summary> 
    /// <param name="file"> 
    /// The file. 
    /// </param> 
    /// <returns> 
    /// Is file loaded 
    /// </returns> 
    private bool Load(string file) 
    { 
     var map = new ExeConfigurationFileMap { ExeConfigFilename = file }; 
     this.config = ConfigurationManager.OpenMappedExeConfiguration(map, ConfigurationUserLevel.None); 

     var xml = new XmlDocument(); 
     using (var stream = new FileStream(file, FileMode.Open, FileAccess.Read)) 
     { 
      xml.Load(stream); 
     } 

     // var cfgSections = xml.GetElementsByTagName("configSections"); 

     // if (cfgSections.Count > 0) 
     // { 
     // foreach (XmlNode node in cfgSections[0].ChildNodes) 
     // { 
     // var type = System.Activator.CreateInstance(
     // Type.GetType(node.Attributes["type"].Value)) 
     // as IConfigurationSectionHandler; 

     // if (type == null) continue; 

     // customSections.Add(node.Attributes["name"].Value, type); 
     // } 
     // } 
     return this.config.HasFile; 
    } 

    /// <summary> 
    /// The build app settings. 
    /// </summary> 
    /// <returns> 
    /// The <see cref="NameValueCollection"/>. 
    /// </returns> 
    private NameValueCollection BuildAppSettings() 
    { 
     var coll = new NameValueCollection(); 

     foreach (var key in this.config.AppSettings.Settings.AllKeys) 
     { 
      coll.Add(key, this.config.AppSettings.Settings[key].Value); 
     } 

     return coll; 
    } 
} 
+1

Hoạt động tốt. Bạn phải thêm không gian tên, System.Collections.Specialized System.Configuration System.Configuration.Internal. Bạn cũng phải thêm tham chiếu đến System.Configuration.dll. – Jim

Các vấn đề liên quan