簡體   English   中英

如何在不重新編譯VS2008中的解決方案的情況下熱交換引用的DLL?

[英]How can I hot swap referenced DLL's without recompiling the Solution in VS2008?

我們的解決方案引用了一個DLL,用於通過以太網與某些硬件進行通信。 我們已經創建了第二個DLL,可用於模擬硬件,因此我們的開發人員不需要在每個桌面上都使用所述硬件。

軟件不應該知道它是使用真實硬件還是模擬器。 我們如何交換引用而無需重新編譯解決方案?

我們可以只指定兩個引用相同,只需注冊/取消注冊我們想要引用的正確的DLL嗎?

[更新]注意:第一個DLL是第三方DLL,我們也沒有訪問權限。 第二個DLL是我們用C ++創建的。 我們的應用程序是用C#編寫的。

使兩個DLL實現一個通用接口(ICommunicateToYourHardware)並編寫應用程序以通過反射而不是通過引用來發現DLL。

每個請求添加樣本

此示例中的接口稱為IAuthenticate,但您可以使用其中的任何接口。 在這種情況下,我實際上正在尋找任何數量的IAuthenticate類。 在您的情況下,如果不同的DLL放置在相同的相對路徑中,則相同的編譯將引入不同的DLL。

 // We need a container for the DLL files that we find and then a container for the instances of 
    // the plug ins created from the dlls. In this test we are only really looking for One such plug in
    // but I prefer to use collections for such things as it allows for a more scalable design. This technique
    // works for 1, 100, or more plugins and/or methods.
    private List<string> _DLLS;
    private List<iAuthenticate> _PlugIns;

    private int LoadPlugIns(string Path)
    {
        /// Within the designated Path (and in all subdirectories) locate all .dll files and put the path 
        /// to these files in a collection.
        GetDLLS(Path);
        foreach (string dirName in Directory.GetDirectories(Path))
        {
            LoadPlugIns(dirName);
        }

        // For each .dll file, inspect it (using reflection) to determine if it is of the iAuthenticate Type
        // if it is, create and instance of the object and store it in a collection, and assign a delegate to 
        // invoke its Authenticate method from the host application.
        foreach (string DLL in _DLLS)

        {
            Assembly myAssembly = Assembly.LoadFrom(DLL);
            Type[] Types = myAssembly.GetTypes();
            foreach (Type myType in Types)
            {
                Type T = myType.GetInterface("iAuthenticate");
               if (T != null)
                {
                    if (_PlugIns == null) { _PlugIns = new List<iAuthenticate>(); }
                    _PlugIns.Add((iAuthenticate)myAssembly.CreateInstance(myType.FullName));
                }
            }
            foreach (iAuthenticate iAuth in _PlugIns)
            {
                this.Authorize += iAuth.Authenticate;
            }
        }
        return _PlugIns.Count;
   }

    private void GetDLLS(string Path)
    {
        if (_DLLS == null){_DLLS = new List<string>();}
        foreach (string filename in Directory.GetFiles(Path, "*.dll")) 
        {
            _DLLS.Add(filename);
        }
    }

一旦我們通過反射獲得了引用集,我們就可以像這樣調用它的方法:

    private void btnLogon_Click(object sender, EventArgs e)
    {
        try
        {
            if (Authorize.Invoke(txtUsername.Text, txtPassword.Text, txtPath.Text))
            {
                this.BackgroundImage = TelefloraDemo.Properties.Resources._189469;
                this.pnlLogon.Visible = false;
                MessageBox.Show("You have Logged On!");
            }
        }
        catch (AuthenticationException aex)
        {
            DemoCode.LogException(aex);
            MessageBox.Show(aex.ToString());
        }
        catch (Exception ex)
        {
            DemoCode.LogException(ex);
            MessageBox.Show("No Authenticator");
        }

    }

    public delegate bool Authenticate(string Username,string Password,string Path);
    public event Authenticate Authorize;

現在,顯然你的里程可能會有所不同,但這應該會讓你走上成功之路。 (是的,還有其他方法,我喜歡這個..)

MEF(托管擴展性框架)使得執行此類操作變得非常容易。 只需確保您的真實和模擬界面導出相同的合同並使用MEF組合來注入所需的版本。

這是一個如何使用它的簡單示例

這是來自MSDN

您可以使用應用程序或計算機配置文件中的條目將程序集綁定引用重定向到程序集的另一個版本。 您可以將引用重定向到.NET Framework程序集,第三方程序集或您自己的應用程序的程序集。 每個版本的.NET Framework都有一個計算機配置文件,該文件中的任何重定向信息都會影響在該.NET Framework版本下運行的所有應用程序。

引用它們並使用工廠類來創建適當的接口。 然后,您可以使用某種外部機制:配置文件,注冊表項,計算機名稱,構建標識符等...以使工廠發出正確的接口。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM