ไฟล์การกำหนดค่า C # DLL


191

ฉันกำลังพยายามเพิ่มไฟล์ app.config ลงใน DLL ของฉัน แต่ความพยายามทั้งหมดล้มเหลว

ตาม MusicGenesis ใน 'การใส่ข้อมูลการกำหนดค่าใน DLL ' สิ่งนี้ไม่ควรมีปัญหา เห็นได้ชัดว่าฉันกำลังทำอะไรผิด ...

รหัสต่อไปนี้ควรส่งคืน ConnectionString ของฉันจาก DLL ของฉัน:

return ConfigurationManager.AppSettings["ConnectionString"];

อย่างไรก็ตามเมื่อฉันคัดลอกไฟล์ app.config ไปยังแอปพลิเคชันคอนโซลของฉันมันทำงานได้ดี

ความคิดใด ๆ


อ้างอิงถึงการโพสต์ที่อ้างถึง: หากชื่อของ dll คือ MyDll.dll ไฟล์กำหนดค่าควรเป็น MyDLL.dll.config ดังนั้นถ้าคุณอ่านการตั้งค่าจากภายใน dll มันควรอ้างถึงการตั้งค่าของตัวเองใช่มั้ย
MegaByte

11
ไม่สำคัญว่ารหัสจะถามอะไร - กำลังมองหาไฟล์ตามที่ระบุไว้สำหรับ AppDomain: AppDomain.CurrentDomain.SetupInformation.ConfigurationFile การตั้งค่าไฟล์
Marc Gravell

หมายเหตุ: คำถาม "การใส่ข้อมูลการกำหนดค่าใน DLL" เป็นเรื่องเกี่ยวกับการแยกรหัสการกำหนดค่าของแอปของคุณลงในห้องสมุดเพื่อให้แยกออกจากรหัสแอปหลัก สิ่งนี้แตกต่างจากไฟล์กำหนดค่าแยกต่างหากและพิเศษสำหรับ DLL ด้วยตัวมันเอง
Chris Ammerman

ดูโพสต์นี้ [ใส่ลิงค์คำอธิบายที่นี่] [1], เป็นทางออกสำหรับฉัน [1]: stackoverflow.com/questions/2389290//
dhailis

ดูโพสต์นี้ [วิธีโหลดไฟล์การตั้งค่าแอปพลิเคชันแยกต่างหากแบบไดนามิกและผสานกับการตั้งค่าปัจจุบัน]] [1] อาจเป็น helpfu [1]: stackoverflow.com/questions/2389290/…
dhailis

คำตอบ:


277

มันไม่สำคัญเลยที่จะสร้างไฟล์. NET สำหรับ. DLL และด้วยเหตุผลที่ดี กลไกการกำหนดค่า. NET มีคุณสมบัติมากมายที่ติดตั้งไว้ภายในเพื่อให้ง่ายต่อการอัพเกรด / อัปเดตแอพและเพื่อปกป้องแอปที่ติดตั้งจากการเหยียบย่ำไฟล์การกำหนดค่าอื่น ๆ

มีความแตกต่างอย่างมากระหว่างวิธีการใช้ DLL กับวิธีการใช้แอปพลิเคชัน คุณไม่น่าจะติดตั้งแอปพลิเคชันหลายชุดในเครื่องเดียวกันสำหรับผู้ใช้รายเดียวกัน แต่คุณอาจมีแอพหรือไลบรารี่ที่แตกต่างกัน 100 แอปทั้งหมดใช้ประโยชน์จาก. NET DLL บางตัว

ในขณะที่ไม่จำเป็นต้องติดตามการตั้งค่าแยกต่างหากสำหรับสำเนาของแอพที่แตกต่างกันภายในโปรไฟล์ผู้ใช้หนึ่งโปรไฟล์มันไม่น่าเป็นไปได้มากที่คุณจะต้องการให้การใช้งาน DLL ที่แตกต่างกันทั้งหมดเพื่อแบ่งปันการกำหนดค่า ด้วยเหตุผลนี้เมื่อคุณดึงข้อมูลวัตถุการกำหนดค่าโดยใช้วิธี "ปกติ" วัตถุที่คุณได้รับกลับมาจะเชื่อมโยงกับการกำหนดค่าของโดเมนแอพที่คุณใช้งานอยู่แทนที่จะเป็นแอสเซมบลีเฉพาะ

App Domain ถูกผูกไว้กับชุดประกอบรูทซึ่งโหลดชุดประกอบซึ่งรหัสของคุณเป็นจริงในกรณีส่วนใหญ่จะเป็นชุดประกอบของ. EXE หลักของคุณซึ่งเป็นชุดโหลด. DLL เป็นไปได้ที่จะหมุนโดเมนแอปอื่นภายในแอปพลิเคชัน แต่คุณต้องให้ข้อมูลอย่างชัดเจนเกี่ยวกับแอสเซมบลีรูทของโดเมนแอปนั้น

ด้วยเหตุนี้กระบวนการในการสร้างไฟล์ปรับแต่งเฉพาะไลบรารีจึงไม่สะดวก มันเป็นกระบวนการเดียวกับที่คุณจะใช้สำหรับการสร้างโดยพลไฟล์ config แบบพกพาไม่เชื่อมโยงกับการชุมนุมใด ๆ โดยเฉพาะ แต่ที่คุณต้องการที่จะทำให้การใช้งานของเค้าร่าง XML .NET ของส่วนปรับแต่งการตั้งค่าและองค์ประกอบกลไก ฯลฯ สร้างความนี้สร้างExeConfigurationFileMapวัตถุ การโหลดข้อมูลเพื่อระบุตำแหน่งที่ไฟล์ config ConfigurationManagerจะถูกเก็บไว้แล้วโทร OpenMappedExeConfigurationที่จะเปิดมันขึ้นไปใหม่Configurationเช่น สิ่งนี้จะตัดคุณออกจากการป้องกันเวอร์ชันที่เสนอโดยกลไกการสร้างพา ธ อัตโนมัติ

คุณอาจใช้ห้องสมุดนี้ในการตั้งค่าภายในองค์กรและไม่น่าเป็นไปได้ที่คุณจะมีแอพจำนวนมากที่ใช้งานภายในเครื่อง / ผู้ใช้รายใดรายหนึ่ง แต่ถ้าไม่มีมีบางสิ่งที่คุณควรจำไว้ หากคุณใช้ไฟล์กำหนดค่าส่วนกลางเดียวสำหรับ DLL ของคุณโดยไม่คำนึงถึงแอปที่อ้างอิงถึงไฟล์คุณต้องกังวลเกี่ยวกับความขัดแย้งในการเข้าถึง หากแอปสองตัวที่อ้างอิงไลบรารีของคุณกำลังทำงานในเวลาเดียวกันแต่ละแอปจะเป็นของตัวเองConfigurationเปิดวัตถุจากนั้นเมื่อแอปบันทึกการเปลี่ยนแปลงมันจะทำให้เกิดข้อยกเว้นในครั้งถัดไปที่คุณพยายามดึงหรือบันทึกข้อมูลในแอปอื่น

วิธีที่ปลอดภัยและง่ายที่สุดในการหลีกเลี่ยงปัญหานี้คือต้องการให้แอสเซมบลีที่กำลังโหลด DLL ของคุณยังให้ข้อมูลบางอย่างเกี่ยวกับตัวเองหรือตรวจสอบโดยการตรวจสอบโดเมนแอพของแอสเซมบลีอ้างอิง ใช้สิ่งนี้เพื่อสร้างโครงสร้างโฟลเดอร์สำหรับเก็บไฟล์กำหนดค่าผู้ใช้แยกต่างหากสำหรับแต่ละแอปที่อ้างถึง DLL ของคุณ

หากคุณแน่ใจว่าคุณต้องการตั้งค่าส่วนกลางสำหรับ DLL ของคุณไม่ว่าจะถูกอ้างอิงที่ไหนคุณจะต้องระบุตำแหน่งของคุณแทนการใช้. NET จะหาตำแหน่งที่เหมาะสมโดยอัตโนมัติ นอกจากนี้คุณจะต้องเข้มงวดเกี่ยวกับการจัดการการเข้าถึงไฟล์ คุณจะต้องแคชให้มากที่สุดเท่าที่จะเป็นไปได้เก็บConfigurationอินสแตนซ์ไว้รอบ ๆ เท่านั้นตราบใดที่ใช้ในการโหลดหรือบันทึกเปิดทันทีก่อนและทิ้งทันทีหลังจากนั้น และในที่สุดคุณจะต้องมีกลไกการล็อคเพื่อป้องกันไฟล์ในขณะที่มันกำลังถูกแก้ไขโดยหนึ่งในแอพที่ใช้ไลบรารี


ฉันคิดว่ากลไกการซิงค์ควรจะเป็น "ชื่อเหตุการณ์" ฯลฯ เพราะมันข้ามกระบวนการ
จาค็อบ

8
: / Meh Ours เป็นแอปองค์กรขนาดใหญ่ที่มี. exe หลักที่เขียนโดยคนในเขตเวลาที่แตกต่างกันและโมดูลที่แสดงโดย DLLs ต่างๆและเชื่อมโยงแบบไดนามิกผ่านกรอบงานปลั๊กอินที่กำหนดเอง ทั้งหมดนี้ "คุณจะต้องตรวจสอบให้แน่ใจว่าหลาย ๆ แอปสามารถใช้ DLL ของคุณพร้อมกันได้" ความผิดพลาดอย่างแน่นอน
JohnL4

นอกจากนี้ในส่วนใหญ่ของอาชีพของฉันฉันได้เห็นกลไกการแชร์วัตถุทั่วไปที่น่ารักเหล่านี้ถูกเพิกเฉยอย่างสมบูรณ์โดยทีมที่สร้าง DLLs (หรือ JARs) ที่สามารถใช้ได้ในบริบทเดียวเท่านั้น (และต้องมีอยู่หรือแอปล้มเหลว ) พวกมันอาจจะถูกผูกมัดแบบคงที่เช่นกัน
JohnL4

1
"การพูดในเชิงสถิติคุณอาจใช้ห้องสมุดนี้ในการตั้งค่าภายในและไม่น่าเป็นไปได้ที่คุณจะมีแอพจำนวนมากที่ใช้งานภายในเครื่อง / ผู้ใช้รายใดรายหนึ่ง" ความแตกต่างระหว่างภาคทฤษฎีและภาคปฏิบัติทำให้ฉันไม่พอใจ
JohnL4

1
@Panzercrisis คุณลักษณะการตั้งค่าการตั้งค่าของ Visual Studio จะสร้างพา ธ เฉพาะเวอร์ชันสำหรับการตั้งค่าผู้ใช้ทั้งหมดโดยอัตโนมัติ ดู: stackoverflow.com/questions/35778528/…
Deantwo

101

หากคุณต้องการอ่านการตั้งค่าจากไฟล์กำหนดค่าของ DLL แต่ไม่ได้มาจากแอปพลิเคชันรูท web.config หรือ app.config ให้ใช้รหัสด้านล่างเพื่ออ่านการกำหนดค่าใน dll

var appConfig = ConfigurationManager.OpenExeConfiguration(Assembly.GetExecutingAssembly().Location);
string dllConfigData = appConfig.AppSettings.Settings["dllConfigData"].Value;

ใน C ++ ที่ได้รับการจัดการสำหรับระบบ VS 2008 :: การกำหนดค่า :: การกำหนดค่า ^ appConfig = ConfigurationManager :: OpenExeConfiguration (แอสเซมบลี :: GetExecutingAssembly () -> ตำแหน่ง); String ^ name = appConfig-> AppSettings-> Settings ["name"] -> Value;
Hans

ขอบคุณนี่แก้ปัญหาของฉันได้จริงๆ ฉันได้รับการจัดการกับปัญหานี้ประมาณสองวันและไม่ได้รับการทำงานจนกว่าจะถึงตอนนี้ ขณะที่การดีบักการทดสอบ ConfigurationManager กำลังอ่านจาก machine.config - ฉันคิดว่า - เนื่องจากสตริงการเชื่อมต่อที่ดึงออกมานั้นมีความเกี่ยวกับ SQLExpress - สตริงการเชื่อมต่อที่ฉันไม่ได้แสดงไว้ -
yopez83

19

ฉันมีปัญหาเดียวกันและค้นหาเว็บเป็นเวลาหลายชั่วโมง แต่ฉันไม่พบวิธีแก้ปัญหาใด ๆ ดังนั้นฉันจึงสร้างของตัวเอง ฉันสงสัยว่าทำไมระบบการกำหนดค่า. net จึงไม่ยืดหยุ่น

พื้นหลัง: ฉันต้องการให้ DAL.dll ของฉันมีไฟล์ปรับแต่งของตัวเองสำหรับฐานข้อมูลและการตั้งค่า DAL ฉันต้องการ app.config สำหรับ Enterprise Library และการกำหนดค่าของตัวเอง ดังนั้นฉันต้องการทั้ง app.config และ dll.config

สิ่งที่ฉันไม่ต้องการทำคือการส่งผ่านคุณสมบัติ / การตั้งค่าทุกอย่างจากแอปไปยังเลเยอร์ DAL ของฉัน!

เพื่อโก่ง "AppDomain.CurrentDomain.SetupInformation.ConfigurationFile" เป็นไปไม่ได้เพราะฉันต้องการมันสำหรับพฤติกรรม app.config ปกติ

ข้อกำหนด / มุมมองของฉันคือ:

  • ไม่มีการคัดลอกอะไรจาก ClassLibrary1.dll.config ไปยัง WindowsFormsApplication1.exe.config ด้วยตนเองเพราะสิ่งนี้ไม่สามารถผลิตได้สำหรับผู้พัฒนารายอื่น
  • คงการใช้งานการพิมพ์ที่รัดกุม "Properties.Settings.Default.NameOfValue" (พฤติกรรมการตั้งค่า) เพราะฉันคิดว่านี่เป็นคุณสมบัติที่สำคัญและฉันไม่ต้องการที่จะสูญเสียมัน
  • ฉันพบว่า ApplicationSettingsBase ไม่มีไฟล์ของคุณเองหรือกำหนดเองหรือจัดการไฟล์ปรับแต่ง (ฟิลด์ที่จำเป็นทั้งหมดเป็นแบบส่วนตัวในคลาสเหล่านี้)
  • การใช้การเปลี่ยนเส้นทางไฟล์ "configSource" เป็นไปไม่ได้เพราะเราจะต้องคัดลอก / เขียน ClassLibrary1.dll.config อีกครั้งและให้ไฟล์ XML หลายไฟล์สำหรับหลายส่วน (ฉันไม่ชอบสิ่งนี้)
  • ฉันไม่ชอบที่จะเขียน SettingsProvider ของฉันเองสำหรับงานง่ายๆนี้เพราะ MSDN แนะนำเพราะฉันคิดว่ามันจะมากเกินไป
  • ฉันต้องการเฉพาะแอปพลิเคชันส่วนการตั้งค่าและการเชื่อมต่อสายสัญญาณจากไฟล์ปรับแต่ง

ฉันมากับการแก้ไขไฟล์ Settings.cs และใช้วิธีการที่เปิด ClassLibrary1.dll.config และอ่านข้อมูลส่วนในฟิลด์ส่วนตัว หลังจากนั้นฉันได้แทนที่ "this [string propertyName]" ดังนั้น Settings.Desginer.cs ที่สร้างขึ้นจะเรียกใช้เป็นคุณสมบัติใหม่ของฉันแทนที่จะเป็นคลาสพื้นฐาน มีการตั้งค่าอ่านจากรายการ

ในที่สุดก็มีรหัสต่อไปนี้:

internal sealed partial class Settings
{
    private List<ConfigurationElement> list;

    /// <summary>
    /// Initializes a new instance of the <see cref="Settings"/> class.
    /// </summary>
    public Settings()
    {
        this.OpenAndStoreConfiguration();
    }

    /// <summary>
    /// Opens the dll.config file and reads its sections into a private List of ConfigurationElement.
    /// </summary>
    private void OpenAndStoreConfiguration()
    {
        string codebase = System.Reflection.Assembly.GetExecutingAssembly().CodeBase;
        Uri p = new Uri(codebase);
        string localPath = p.LocalPath;
        string executingFilename = System.IO.Path.GetFileNameWithoutExtension(localPath);
        string sectionGroupName = "applicationSettings";
        string sectionName = executingFilename + ".Properties.Settings";
        string configName = localPath + ".config";
        ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap();
        fileMap.ExeConfigFilename = configName;
        Configuration config = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);

        // read section of properties
        var sectionGroup = config.GetSectionGroup(sectionGroupName);
        var settingsSection = (ClientSettingsSection)sectionGroup.Sections[sectionName];
        list = settingsSection.Settings.OfType<ConfigurationElement>().ToList();

        // read section of Connectionstrings
        var sections = config.Sections.OfType<ConfigurationSection>();
        var connSection = (from section in sections
                           where section.GetType() == typeof(ConnectionStringsSection)
                           select section).FirstOrDefault() as ConnectionStringsSection;
        if (connSection != null)
        {
            list.AddRange(connSection.ConnectionStrings.Cast<ConfigurationElement>());
        }
    }

    /// <summary>
    /// Gets or sets the <see cref="System.Object"/> with the specified property name.
    /// </summary>
    /// <value></value>
    public override object this[string propertyName]
    {
        get
        {
            var result = (from item in list
                         where Convert.ToString(item.ElementInformation.Properties["name"].Value) == propertyName
                         select item).FirstOrDefault();
            if (result != null)
            {
                if (result.ElementInformation.Type == typeof(ConnectionStringSettings))
                {
                    return result.ElementInformation.Properties["connectionString"].Value;
                }
                else if (result.ElementInformation.Type == typeof(SettingElement))
                {
                    return result.ElementInformation.Properties["value"].Value;
                }
            }
            return null;
        }
        // ignore
        set
        {
            base[propertyName] = value;
        }
    }

คุณจะต้องคัดลอก ClassLibrary1.dll.config ของคุณจากไดเรกทอรีผลลัพธ์ ClassLibrary1 ไปยังไดเรกทอรีผลลัพธ์ของแอปพลิเคชันของคุณ บางทีบางคนอาจพบว่ามีประโยชน์


14

เมื่อใช้ ConfigurationManager ฉันค่อนข้างแน่ใจว่ากำลังโหลดไฟล์กระบวนการ / AppDomainการกำหนดค่า (app.config / web.config) หากคุณต้องการโหลดไฟล์ปรับแต่งเฉพาะคุณจะต้องขอไฟล์นั้นตามชื่อ ...

คุณสามารถลอง:

var config = ConfigurationManager.OpenExeConfiguration("foo.dll");
config.ConnectionStrings. [etc]

ตามที่อ้างถึงโพสต์: ถ้าชื่อของ dll คือ MyDll.dll แล้วไฟล์ config ควรเป็น MyDLL.dll.config ดังนั้นหากคุณอ่านการตั้งค่าคอนฟิกจากภายใน dll มันควรอ้างถึงการกำหนดค่าของตัวเองใช่มั้ย
MegaByte

1
ไม่ ... ฉันไม่คิดอย่างนั้น "จากกับ dll" ทำให้ไม่มีราคา โดยค่าเริ่มต้นมันจะดูที่ไฟล์กำหนดค่าที่กำหนดไว้สำหรับ AppDomain: my.exe.config
Marc Gravell

1
โดยเฉพาะอย่างยิ่งการตั้งค่า AppDomain.CurrentDomain.SetupInformation.ConfigurationFile
Marc Gravell

หมายเหตุ: ฉันลองใช้ OpenExeConfiguration แล้วและฉันก็ไม่แน่ใจเหมือนกัน บางทีแค่รวมการกำหนดค่ากับ app.config
Marc Gravell

มันสามารถทำได้ ... แต่ไม่ได้อยู่กับชนิดเดียวกันของการสนับสนุนและความปลอดภัยเป็นไฟล์ app.config สำหรับข้อ EXE ดูคำตอบของฉัน
Chris Ammerman

13

ConfigurationManager.AppSettings ส่งคืนการตั้งค่าที่กำหนดไว้สำหรับแอปพลิเคชันไม่ใช่สำหรับ DLL เฉพาะคุณสามารถเข้าถึงได้ แต่เป็นการตั้งค่าแอปพลิเคชันที่จะถูกส่งคืน

หากคุณใช้งานคุณ dll จากแอพพลิเคชั่นอื่นแล้ว ConnectionString จะอยู่ในการตั้งค่าแอพพลิเคชั่น


6

ฉันรู้ว่ามันสายไปงานปาร์ตี้ แต่ฉันคิดว่าฉันจะแบ่งปันโซลูชันที่ฉันใช้กับ DLL

ฉันเป็นโรงเรียนแห่งการคิดของ KISS ดังนั้นเมื่อฉันมี. NET DLL ที่ต้องการเก็บจุดข้อมูลภายนอกที่ควบคุมการทำงานหรือตำแหน่งที่ไป ฯลฯ ฉันก็แค่สร้าง "config" ที่มีคุณสมบัติสาธารณะเท่านั้น ที่เก็บจุดข้อมูลทั้งหมดที่ต้องการและฉันต้องการให้สามารถควบคุมภายนอกไปยัง DLL เพื่อป้องกันการคอมไพล์ใหม่เพื่อทำการเปลี่ยนแปลง จากนั้นฉันใช้. XML Serializing ของการบันทึกและโหลดการแสดงวัตถุของคลาสไปยังไฟล์

มีหลายวิธีในการจัดการอ่านและเข้าถึงจาก Singleton, คลาสยูทิลิตี้คงที่, วิธีการขยาย ฯลฯ ขึ้นอยู่กับว่า DLL ของคุณมีโครงสร้างและวิธีใดที่จะเหมาะสมกับ DLL ของคุณได้ดีที่สุด


ฉันใช้วิธีการนี้เช่นกันและมีความสุขกับวิธีการที่ได้ผล
เดฟ

4

คุณถูกต้องคุณสามารถอ่านไฟล์กำหนดค่าของ dll ฉันดิ้นรนกับสิ่งนี้เป็นเวลาหนึ่งวันจนกระทั่งฉันพบว่าไฟล์ config ของฉันเป็นปัญหา ดูรหัสของฉันด้านล่าง มันสามารถวิ่งได้

        ExeConfigurationFileMap map = new ExeConfigurationFileMap();
        map.ExeConfigFilename = Assembly.GetExecutingAssembly().Location + ".config";
        Configuration libConfig = ConfigurationManager.OpenMappedExeConfiguration(map, ConfigurationUserLevel.None);
        AppSettingsSection section = (libConfig.GetSection("appSettings") as AppSettingsSection);
        Console.WriteLine(section.Settings["dnd_shortcodes"].Value);

ของฉันPlugin1.dll.configดูด้านล่าง;

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
 <appSettings>
  <add key="cmd_location" value="http://..."/>
  <add key="dnd_shortcodes" value="142,145,146,157,165,167,168,171,173,176,178,404,40"/>
 </appSettings>
</configuration>

ฉันพบว่าไฟล์ปรับแต่งของฉันไม่มี<appSettings>แท็กดังนั้นมองไปรอบ ๆ ปัญหาของคุณอาจแตกต่างกัน แต่ไม่ไกลจากของฉัน


3

เนื่องจากแอสเซมบลีอยู่ในแคชชั่วคราวคุณควรรวมเส้นทางเพื่อรับการตั้งค่าของ dll:

var appConfig = ConfigurationManager.OpenExeConfiguration(
    Path.Combine(Environment.CurrentDirectory, Assembly.GetExecutingAssembly().ManifestModule.Name));

แทน "Path.Combine (Environment.CurrentDirectory, Assembly.GetExecutingAssembly (). ManifestModule.Name)" คุณสามารถใช้ "Assembly.GetExecutingAssembly () สถานที่"
Cadburry

3

หากคุณกำลังใช้ห้องสมุดที่ค้นหาความเชื่อมั่นจำนวนมากที่อยู่เบื้องหลังเช่น WCF คุณอาจลองทำสิ่งนี้:

AppDomain.CurrentDomain.SetData("APP_CONFIG_FILE", "MyWcfClientWrapper.dll.config");

หรือใน PowerShell:

[AppDomain]::CurrentDomain.SetData("APP_CONFIG_FILE", "MyWcfClientWrapper.dll.config")

IMO เทคนิคนี้มีกลิ่นรหัสและเหมาะสำหรับใช้ในการเขียนสคริปต์แบบเฉพาะกิจเท่านั้น หากคุณพบว่าตัวเองต้องการทำสิ่งนี้ในรหัสการผลิตอาจถึงเวลาสำหรับการตรวจสอบทางสถาปัตยกรรม

ไม่แนะนำให้ใช้สิ่งต่อไปนี้:
เนื่องจากความอยากรู้ด้านเทคนิคนี่เป็นความแตกต่างของธีม คุณสามารถสร้างตัวสร้างแบบคงที่ภายในหนึ่งในชั้นเรียนซึ่งอยู่ใน DLL และทำการโทรนี้จากที่นั่น ฉันจะไม่แนะนำให้ทำเช่นนี้ยกเว้นเป็นทางเลือกสุดท้าย


3

วิธีการแก้ปัญหาเต็มรูปแบบมักจะไม่พบในที่เดียว ...

1) สร้างไฟล์กำหนดค่าแอพและตั้งชื่อมันว่า "yourDllName.dll.config"
2) คลิกขวาที่ไฟล์ปรับแต่งที่สร้างขึ้นใน VS Solution Explorer คลิกคุณสมบัติ
--- ตั้งค่า "Build Action" = เนื้อหา
--- ตั้งค่า "คัดลอกไปยังไดเรกทอรีออก" = เสมอ
3) เพิ่มส่วน appSettings ในไฟล์การกำหนดค่า (yourDllName.dll.config) ด้วย yourKeyName และ yourKeyValue

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <appSettings>
    <add key="yourKeyName" value="yourKeyValue"/>
  </appSettings>
</configuration>

4) เพิ่ม System.Configuration ของคุณอ้างอิง dll / class / project
5) เพิ่มคำสั่งการใช้รหัสของคุณที่คุณต้องการเข้าถึงการตั้งค่า config

using System.Configuration;
using System.Reflection;

6) เพื่อเข้าถึงค่า

string keyValue = ConfigurationManager.OpenExeConfiguration(Assembly.GetExecutingAssembly().Location).AppSettings.Settings["yourKeyName"].Value;

7) ชื่นชมยินดีมันใช้งานได้

IMHO ควรใช้สิ่งนี้เมื่อพัฒนา dll / library ใหม่เท่านั้น

#if (DEBUG && !FINALTESTING)
   string keyValue = ConfigurationManager.OpenExeConfiguration...(see 6 above)
#else
   string keyValue = ConfigurationManager.AppSettings["yourKeyName"];
#endif

ไฟล์กำหนดค่านั้นเป็นข้อมูลอ้างอิงที่ดีมากเมื่อคุณเพิ่มการตั้งค่าแอพของ dll ลงในแอปพลิเคชันจริงของคุณ


3

ดูเหมือนว่าไฟล์กำหนดค่านี้จะทำให้เกิดความสับสนจริง ๆ เนื่องจากการเปลี่ยนแปลงพฤติกรรมของพวกเขาจากสภาพแวดล้อม dev เพื่อการใช้งาน เห็นได้ชัดว่า DLL สามารถมีไฟล์กำหนดค่าของตัวเอง แต่เมื่อคุณคัดลอกและวาง dll (พร้อมกับไฟล์กำหนดค่า) ที่อื่นสิ่งทั้งหมดก็หยุดทำงาน ทางออกเดียวคือการรวมไฟล์ app.config ลงในไฟล์เดียวด้วยตนเองซึ่งผู้บริหารระบบจะใช้งานเท่านั้น สำหรับเช่น myapp.exe จะมีไฟล์ myapp.exe.config ที่มีการตั้งค่าทั้งหมดสำหรับ dlls ทั้งหมดที่ใช้โดย myapp.exe ฉันใช้ VS 2008


2

ฉันพบสิ่งที่ดูเหมือนเป็นวิธีแก้ปัญหาที่ดีสำหรับปัญหานี้ ฉันใช้ VS 2008 C # โซลูชันของฉันเกี่ยวข้องกับการใช้เนมสเปซที่แตกต่างกันระหว่างไฟล์กำหนดค่าหลายไฟล์ ผมเคยโพสต์การแก้ปัญหาบนบล็อกของฉัน: http://tommiecarter.blogspot.com/2011/02/how-to-access-multiple-config-files-in.html

ตัวอย่างเช่น:

เนมสเปซนี้อ่าน / เขียนการตั้งค่า dll:

var x = company.dlllibrary.Properties.Settings.Default.SettingName;
company.dlllibrary.Properties.Settings.Default.SettingName = value;

เนมสเปซนี้อ่าน / เขียนการตั้งค่า exe:

company.exeservice.Properties.Settings.Default.SettingName = value;
var x = company.exeservice.Properties.Settings.Default.SettingName;

มีบางประการที่กล่าวถึงในบทความ HTH


1

ตามที่ Marc บอกว่าเป็นไปไม่ได้ (ถึงแม้ว่า Visual Studio จะช่วยให้คุณเพิ่มไฟล์การกำหนดค่าแอปพลิเคชันในโครงการห้องสมุดคลาส)

คุณอาจต้องการตรวจสอบคลาสAssemblySettingsซึ่งดูเหมือนว่าจะทำให้ไฟล์ config ประกอบเป็นไปได้


0

ในบทความนี้มีการพูดถึงปัญหาที่คล้ายกันและแก้ไขปัญหาของฉันวิธีการโหลดไฟล์การตั้งค่าแอปพลิเคชันแยกต่างหากแบบไดนามิกและรวมกับการตั้งค่าปัจจุบัน? อาจจะเป็น helpfu


ในขณะที่สิ่งนี้อาจตอบคำถามในทางทฤษฎีมันก็ควรที่จะรวมส่วนสำคัญของคำตอบที่นี่และให้ลิงค์สำหรับการอ้างอิง
Adi

0

สำหรับ dll มันไม่ควรขึ้นอยู่กับการกำหนดค่าเนื่องจากการกำหนดค่าเป็นของแอปพลิเคชันและไม่ใช่โดย dll

นี่คือคำอธิบายที่นี่


0

คุณสามารถใช้รหัสนี้:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace GClass1
{
[Guid("D6F88E95-8A27-4ae6-B6DE-0542A0FC7039")]
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
public interface _GesGasConnect
{
    [DispId(1)]
    int SetClass1Ver(string version);


}

[Guid("13FE32AD-4BF8-495f-AB4D-6C61BD463EA4")]
[ClassInterface(ClassInterfaceType.None)]
[ProgId("InterfacesSMS.Setting")]
public class Class1 : _Class1
{
    public Class1() { }


    public int SetClass1(string version)
    {
        return (DateTime.Today.Day);
    }
}
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.