3

today I'd like to know how do you configure your projects in C# WPF which references additional assemblies in a chain. By the "in a chain" I mean something like this:

  • we have application which refers to assembly Plugin
  • Plugin assembly refers Resources where resources used by Plugin are located, eg. images
  • main application does not refers to Resource in any way.

The following image illustrates what I've just said:
Chain-referenced assemblies

The problem is that Resources is not copied to the bin folder of the application, causing Plugin (Ctrl on the image) resources it requires finding failure.

Workaround

There are workarounds for it which are simply to include Resources to references of the main application or use a post-build step and manually copy required files in that step.

Conclusion

Concluding, I'd like to ask how do you deal with that problem. Are the any other solutions besides those I mentioned in workaround section? Am I missing something in the projects' configuration?

SOReader
  • 5,697
  • 5
  • 31
  • 53

2 Answers2

1

Make sure that the output directory in the Plugin project properties is same as the output directory of your application. Otherwise you have to copy files yourself as you do.

Second option would be using embedded resources.

kokoska69
  • 11
  • 1
  • Unfortunately both options are unacceptable. The 'Res' project is usually my 'CommonControls' library, which is quite big - embedding it in 'Ctrl' projects is not a good idea. Coping files is simply annoying and counterproductive :( Nevertheless, thanks for the embedding idea. – SOReader Oct 21 '12 at 23:21
0

If you load the plugin dynamically from a different folder than the EXE, you can also copy its dependencies to the same folder as the plugin and load those assemblies dynamically, as well. You then need to handle AssemblyResolve so that the already-loaded assemblies will be resolved instead of trying to find new assemblies:

AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
    private Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
    {
        var domain = (AppDomain)sender;
        var assemblies = domain.GetAssemblies();
        return assemblies.FirstOrDefault(assembly => assembly.GetName().Name == args.Name.Split(',')[0]);
    }

The code above does a version and strong-naming insensitive match; you can implement your own policy here if you want something stricter.

Dan Bryant
  • 27,329
  • 4
  • 56
  • 102
  • Thanks for that answer but the question is not about dependencies loaded dynamically from code but the "Add reference..." option in a project's context menu in MSVS – SOReader Oct 21 '12 at 23:16