Assembly dependencies issue

0

Situation:

I have tree projects (ZShared, ZSearcher and ZClient) where they will be referenced in each other.

ZShared is a common DLL assembly containing some styles and resources.

ZSearcher is also a DLL assembly with some WPF controls.

ZClient in theory can be anything (WPF app, Winforms, Excel etc.) for testing purposes I have made it as WPF app.

Problem:

When I reference ZShared in ZSearcher it produces two DLL files: ZShared.DLL and ZSearcher.DLL

When ZSearcher is referenced in ZClient, only the ZSearcher is copied to the ZClient folder. That can be solved by referencing the ZShared as well.

But I want the ZSearcher to be working as a standalone app. Like when ZSearcher is referenced then the dependecies should automatically follow.

Therefor I thought perhaps using reflection instead of referencing would solve the issue. But exact same issue happens with reflection.

System.Windows.Markup.XamlParseException HResult=0x80131501
Message='Set property 'System.Windows.ResourceDictionary.Source' threw an exception.' Line number '10' and line position '18'.
Source=PresentationFramework
StackTrace: at System.Windows.Markup.WpfXamlLoader.Load(XamlReader xamlReader, IXamlObjectWriterFactory writerFactory, Boolean skipJournaledProperties, Object rootObject, XamlObjectWriterSettings settings, Uri baseUri) at System.Windows.Markup.WpfXamlLoader.LoadBaml(XamlReader xamlReader, Boolean skipJournaledProperties, Object rootObject, XamlAccessLevel accessLevel, Uri baseUri) at System.Windows.Markup.XamlReader.LoadBaml(Stream stream, ParserContext parserContext, Object parent, Boolean closeStream) at System.Windows.Application.LoadComponent(Object component, Uri resourceLocator) at ZSearcher.SearcherWindow.InitializeComponent() in C:\Users\nn\Desktop\WorkSpaceVS\TestApplication\ZSearcher\SearcherWindow.xaml:line 1

Inner Exception 1: FileNotFoundException: Could not load file or assembly 'ZShared, Culture=neutral' or one of its dependencies. The system cannot find the file specified.

Reproduction of issue:

Create a .NET-Framework C# DLL assembly project (ZShared). This assembly only contains one ResourceDictionary:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

    <SolidColorBrush x:Key="ZSolidColorBrushRed" Color="Red"/>
    <Style x:Key="ZButtonStyle" TargetType="{x:Type Button}">
        <Setter Property="Foreground" Value="Green"/>
    </Style>
</ResourceDictionary>

Create another .NET-Framework C# DLL assembly project (ZSearcher). This assembly contains one Window and once Class:

Searcher.cs class:

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

            return null;
        }
    }
}

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>

Reference the ZShared.DLL in ZSearcher project.

Create a .NET-Framework WPF C# app. This app only contains the MainWindow.

MainWindow.xaml:

<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);
        }
    }
}

Question:

How can I make this ZSearcher assembly to work as a standalone ?

c#
wpf
dll
.net-assembly
asked on Stack Overflow Jun 11, 2020 by Nawed Nabi Zada

1 Answer

1

When MSBuild builds the solution, it needs to have a code-level reference in place between ZSearcher and ZShared in order to detect the dependency properly and copy it to the ZClient bin folder.

Some folks will create a dummy code reference to get around this issue.

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;
        }
    }
}
answered on Stack Overflow Jun 11, 2020 by Keithernet

User contributions licensed under CC BY-SA 3.0