Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/285.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 程序集依赖关系问题_C#_Wpf_Dll_.net Assembly - Fatal编程技术网

C# 程序集依赖关系问题

C# 程序集依赖关系问题,c#,wpf,dll,.net-assembly,C#,Wpf,Dll,.net Assembly,情况: 我有树项目ZShared、ZSearcher和ZClient,它们将在其中相互引用 ZShared是一个常见的DLL程序集,包含一些样式和资源 ZSearcher也是一个带有一些WPF控件的DLL程序集 理论上,ZClient可以是WPF应用程序、Winforms、Excel等的任何内容。出于测试目的,我将其制作为WPF应用程序 问题: 当我在ZSearcher中引用ZShared时,它会生成两个DLL文件:ZShared.DLL和ZSearcher.DLL 在ZClient中引用ZSe

情况:

我有树项目ZShared、ZSearcher和ZClient,它们将在其中相互引用

ZShared是一个常见的DLL程序集,包含一些样式和资源

ZSearcher也是一个带有一些WPF控件的DLL程序集

理论上,ZClient可以是WPF应用程序、Winforms、Excel等的任何内容。出于测试目的,我将其制作为WPF应用程序

问题:

当我在ZSearcher中引用ZShared时,它会生成两个DLL文件:ZShared.DLL和ZSearcher.DLL

在ZClient中引用ZSearcher时,只有ZSearcher被复制到ZClient文件夹。这也可以通过引用ZShared来解决

但是我希望ZSearcher能够作为一个独立的应用程序工作。就像引用ZSearcher一样,依赖项应该自动跟随

因此,我认为也许使用反射而不是引用可以解决这个问题。但同样的问题也发生在反射上

System.Windows.Markup.XamlParseException HResult=0x80131501 Message='Set property'System.Windows.ResourceDictionary.Source'抛出 异常。“行号“10”和行位置“18”。 Source=PresentationFramework StackTrace:在 System.Windows.Markup.WpfXamlLoader.LoadXamlReader xamlReader, IXamlObjectWriterFactory writerFactory,布尔型 skipJournaledProperties、Object rootObject、XamlObjectWriterSettings 设置,Uri baseUri位于 System.Windows.Markup.WpfXamlLoader.LoadBamlXamlReader xamlReader, 布尔skipJournaledProperties,对象rootObject,XamlAccessLevel accessLevel,Uri baseUri位于 System.Windows.Markup.XamlReader.LoadBamlStream流,ParserContext parserContext、对象父对象、布尔closeStream位于 System.Windows.Application.LoadComponentObject组件,Uri 位于ZSearcher.SearcherWindow.InitializeComponent的resourceLocator 在里面 C:\Users\nn\Desktop\WorkSpaceVS\TestApplication\ZSearcher\SearcherWindow.xaml:line 一,

内部异常1:FileNotFoundException:无法加载文件或 程序集“ZShared,区域性=中立”或其依赖项之一。这个 系统找不到指定的文件

问题的复制:

创建.NET Framework C DLL程序集项目ZShared。此程序集仅包含一个ResourceDictionary:

SearcherWindow.xaml:

<Window x:Class="ZSearcher.SearcherWindow"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         Height="300" Width="500"
         Title="ZSearcher">

   <Window.Resources>
       <ResourceDictionary>
           <ResourceDictionary.MergedDictionaries>
               <ResourceDictionary Source="pack://Application:,,,/ZShared;component/ZResources.xaml"/>
           </ResourceDictionary.MergedDictionaries>
       </ResourceDictionary>
    </Window.Resources>

    <Grid>
        <StackPanel Margin="20">
            <TextBlock Text="SolidColorBrush test" Foreground="{DynamicResource ZSolidColorBrushRed}"/>
            <Button Content="Button style test" Style="{DynamicResource ZButtonStyle}"/>
        </StackPanel>
    </Grid>
</Window>
<Window x:Class="ZClient.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="ZClient" Width="400" Height="200">
    <Grid>
        <Button Content="Open searcher" Click="OpenSearcher_Click" Width="100" Height="30"/>
    </Grid>
</Window>
MainWindow.cs

using System.Reflection;
using System.Windows;
using ZSearcher;

namespace ZClient
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void OpenSearcher_Click(object sender, RoutedEventArgs e)
        {
            //Referenced tester
            var referenceTest = Searcher.Search("Test");

            //Reflection tester
            var test = Test("Search");
        }

        private static object Test(string methodName)
        {
            var assembly = Assembly.LoadFrom(@"C:\Users\nn\Desktop\WorkSpaceVS\TestApplication\ZSearcher\bin\Debug\ZSearcher.DLL");
            var type = assembly.GetType("ZSearcher.Searcher");

            if (type == null) return null;
            var methodInfo = type.GetMethod(methodName, BindingFlags.Public | BindingFlags.Static);

            if (methodInfo == null) return null;
            var parametersArray = new object[] { "Test" };

            return methodInfo.Invoke(null, parametersArray);
        }
    }
}
问题:


如何使此ZSearcher程序集作为独立程序运行?

当MSBuild生成解决方案时,它需要在ZSearcher和ZShared之间放置一个代码级引用,以便正确检测依赖项并将其复制到ZClient bin文件夹

有些人会创建一个虚拟代码引用来回避这个问题

using ZShared;

namespace ZSearcher
{
    public static class Searcher
    {
        static Searcher()
        {
            // Reference something from ZShared here...
        }

        public static object Search(string param)
        {
            var window = new SearcherWindow();
            window.ShowDialog();

            return null;
        }
    }
}

令人兴奋!使用反射时,不涉及复制。我的假设是,它只是从绝对路径读取DLL。为什么需要虚拟参考?真奇怪。我个人并没有遇到过这个问题,但我在某地和其他地方发现了很多人,他们在许多版本的VisualStudio中为此奋斗了多年。这一切都归结为MSBuild中的黑箱魔法。当两个程序集之间存在实际代码引用时,MSBuild将确保正确复制它们。然而,仅仅依赖项定义是不够的。很可能MSBuild只是想表现得太聪明。
using System.Reflection;
using System.Windows;
using ZSearcher;

namespace ZClient
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void OpenSearcher_Click(object sender, RoutedEventArgs e)
        {
            //Referenced tester
            var referenceTest = Searcher.Search("Test");

            //Reflection tester
            var test = Test("Search");
        }

        private static object Test(string methodName)
        {
            var assembly = Assembly.LoadFrom(@"C:\Users\nn\Desktop\WorkSpaceVS\TestApplication\ZSearcher\bin\Debug\ZSearcher.DLL");
            var type = assembly.GetType("ZSearcher.Searcher");

            if (type == null) return null;
            var methodInfo = type.GetMethod(methodName, BindingFlags.Public | BindingFlags.Static);

            if (methodInfo == null) return null;
            var parametersArray = new object[] { "Test" };

            return methodInfo.Invoke(null, parametersArray);
        }
    }
}
using ZShared;

namespace ZSearcher
{
    public static class Searcher
    {
        static Searcher()
        {
            // Reference something from ZShared here...
        }

        public static object Search(string param)
        {
            var window = new SearcherWindow();
            window.ShowDialog();

            return null;
        }
    }
}