0

I have a solution that contains 2 projects: a class library called plugin and a console app called myconsole. They both use a NuGet package i.e. log4net. They have to meet these requirements:

  • myconsole is not allowed to reference plugin.dll, but it needs to load it via reflection at run time

  • plugin.dll has to be available in a directory called plugins that is relative to myconsole.exe

  • log4net.dll has to be available in a directory called dlls that is also relative to myconsole.exe

I need this deployment to happen when I build the solution in the IDE. Ideally I need this file structure to be produced by the IDE build:

[Z:\Staging]
- [Dlls]
  - log4net.dll
- [Plugins]
  - plugin.dll
- myconsole.exe

I was thinking to update each project and add a MSBuild target that runs after the build to copy the content of the the output directory (bin\debug) to the destination directory that I need. This approach has some issues:

  1. It does not scale well if I need to add more projects with different deployment requirements.
  2. If the projects are built in parallel then they both need to copy log4net.dll to the same location. If this happens at the same time then I get warnings because the file is in use and retries are attempted. It works eventually, but I take it as a hint that I am doing something wrong. To workaround this I could filter the project output to deploy only what is produced by the project - which means I am able to deploy only myconsole.exe and plugin.dll, but not log4net.dll. I would have to deploy this one manually, probably after being done with both projects (solution-level event?). This seems too complicated...

What is the correct way to implement this in MSBuild?

Suiden
  • 622
  • 4
  • 17
  • I think if you want the `log4net` will be in a separated dir, You'll have to load it by reflection too. – baruchiro Jul 26 '19 at 04:19
  • You can see [this](https://stackoverflow.com/a/55982108/839513) Q&A to know how to output the reference to the subfolder. – baruchiro Jul 26 '19 at 04:38
  • But in general, what is your question? Do you ask how to output the reference? This question was answered by the link I gave. Do you ask how to build `dll` to different dir and load it by reflection? – baruchiro Jul 26 '19 at 04:42
  • I am only interested in how to change the reference output using MSBuild. Thank you @Baruch for pointing it out to me. You may want to add this as an answer that I will accept. – Suiden Jul 26 '19 at 12:47

1 Answers1

0

In my opinion, you ask a few questions:

  • How to output the references to a separate folder.
  • How to export a dll without its references.

How to output the references to a separate folder

This question has already been asked, and its answer is somewhat complex, so it is not worth duplicating it.

How to export a dll without its references

You don't want plugin.dll to use its own log4net.dll, because if there is a static field in log4net.dll, it will be reinitialized when you load the plugin.dll at runtime.

Therefore, although you are exporting the plugin.dll to a separate folder, you need to leave the dlls in your executable folder:

Add this to your plugin.csproj file:

<Target Name="DontCopyReferencesToLocal" AfterTargets="ResolveAssemblyReferences">
  <ItemGroup>
    <ReferenceCopyLocalPaths Remove="@(ReferenceCopyLocalPaths)" />
  </ItemGroup>
</Target>

Disclaimer:

I have not checked how the combination of the 2 requirements works together. But I think that as long as each of them works on its own, there is no reason why they should not work together.

baruchiro
  • 5,088
  • 5
  • 44
  • 66
  • My question is how to output a reference to a specific folder. The other thing that you mention "how to export a dll without its references" is not what I had in mind, but it doesn't hurt to learn. Thank you. – Suiden Jul 27 '19 at 05:53
  • @Suiden Your question was not focused and included more topics. – baruchiro Jul 27 '19 at 18:27