簡體   English   中英

未收到MVVM Light Messenger和Dynamic Dll消息

[英]MVVM Light Messenger and Dynamic Dll Messages not received

我正在一個WPF項目中,我們正在使用MVVM Light Messenger和SimpleIOC。 該解決方案有多個項目,提供了與串行/ USB設備一起使用的實現,並且這些實現使用一個公共接口來抽象出各種設備的詳細信息。

在應用程序啟動時,該解決方案在IOC中注冊我們的依賴項:

Kernel.Container.Register<IMainWindow, MainWindow>(Lifestyle.Transient);
//more dependency registrations.

加載MainWindow時,我們會檢測到用戶要使用的設備並進行加載。 但是,由於我們不想將應用程序緊密耦合到設備實現,因此WPF應用程序中沒有直接引用任何設備實現。 加載設備時,我們使用Reflection引入DLL並構造對象,然后傳回公共接口IDevice

用於加載DLL和構造設備的代碼:

public static Assembly GetAssembly(string dll)
{
            var codeBase = Assembly.GetExecutingAssembly().CodeBase;
            var uri = new UriBuilder(codeBase);
            var path = Uri.UnescapeDataString(uri.Path);
            //Load the assembly from the specified path.
            var theDirectory = Path.GetDirectoryName(path);
            var strTempAssmbPath = string.Format(@"{0}\Devices\{1}", theDirectory, dll);
            var theDll = Assembly.LoadFile(strTempAssmbPath);
            return theDll;
}

//Actual code that gets the assembly and loads the IDevice
var assembly = GetAssembly("MyDevice.dll");
(IDevice)Activator.CreateInstance(assembly.GetType(type), ConstructorConstraint);

每個設備使用靜態MessageBus(對我們的消息傳遞庫的直接項目引用)在設備上發生事件時再次將消息發送回應用程序(同樣,允許從WPF應用程序中提取設備實現)。 這是我們的MessageBus實現:

public static class MessageBus
    {
        public static void Send<T>(T message)
        {
            Messenger.Default.Send(message);
        }

        public static void Receive<T>(object subscriber, Action<T> action) where T : MessageBase
        {
            Messenger.Default.Register(subscriber, action);
        }
    }

通過調試器運行應用程序時,這一切都很好,並且一切正常。 但是,在通過構建過程構建了應用程序並打包了安裝程序,然后在QA機器上進行安裝之后,WPF應用程序將像正常情況一樣運行,適當地加載設備,但是MainWindow不會接收到該設備實現發送的消息在運行的應用程序中。

我們現在所擁有的運行理論是,由於設備是在運行時加載的,因此它們無法獲得對消息傳遞庫的相同引用(消息傳遞DLL丟失或設備dll中的引用與引用不相同)在WPF應用程序中)。 我們正在嘗試將Messaging DLL復制到Devices文件夾中,並得到一些混合結果。

在構建和打包應用程序以進行發布之后,為什么我們的應用程序沒有收到設備發送的消息,但是在調試器中可以正常工作?

該解決方案非常難以捉摸,並不能真正解釋其行為,但是我們能夠解決問題。

基本上,我們的構建過程使用ILMerge的開源版本,該版本將依賴項合並到輸出可執行文件中。 作為該過程的一部分,ILMerge版本存在將程序集合並到WPF可執行文件中的問題,而WPF可執行文件不是WPF項目本身中的嵌入式資源。 為了解決該問題,我們必須在WPF項目上有一個MSBuild任務,該任務嵌入了所有引用,以便ILMerge進程可以正確地合並它們。 此處的示例: https : //gist.github.com/thoemmi/3724333

這是事情開始變得有點奇怪的地方。 包含我們的MessageBusMessaging項目在WPF項目中是直接參考,並且正在由我們的構建過程嵌入和合並。 我們的設備DLL無法從生成輸出中的合並程序集中解析那些引用。

為了使一切正常,我們已經修改了構建過程,以將Messaging DLL輸出到與應用程序可執行文件相同的目錄中,並且一切正常。

這不是我們所希望的優雅解決方案,但絕對可以解決我們的問題。

如果有人提出了解決問題的更好答案,我很樂意對其進行測試並將其作為答案。

暫無
暫無

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

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