Build project's components to own .dlls - c#

I have project, which contains lot of classes. I use this project as plugin base for one of my application. This app can load all these plugins from one .dll builded from this project.
Problem is, I need to use these plugins in third-side app. This app can load only one plugin per .dll. I have very few options here. As far as I know, I could create new project for each file and build them. But it is sloppy way how to solve it.
So, is there any way, how to build one project for each of its classes or for groups of classes?
It sounds to me as task for some script. Is possible to achieve this for example with psake or powershell?
Thanks in regards

Well, I believe that they are already doing that in their own bin directories.
That`s if you mean assemblies as components. If you are talking about classes, then you should place them in separate assemblies and use the same approach.
You can right click on assembly and go to properties, build where you can see the 'output path' field as well as 'XML documentation' checkbox which is required for third-side apps to see your XML comments while using .dll-s.

One way I can think of is to create a 'template' project file based on the Plugin project you already have. You can make a copy of the plugin.csproj and then delete all included plugin classes. Using psake and Powershell you can dynamically add the plugin class you need an assembly for and then call MSBuild to build the csproj.
<ItemGroup>
<Compile Include="MyFirstPlugin.cs" />
</ItemGroup>
Adding xml-nodes like this to an csproj-file is easy to do in Powershell.
The pseudo code for the ps script could be something like this;
define list of plugin cs-files
for each plugin cs file
copy template.csproj to plugin.csproj
add xml node to include plugin.cs file
call msbuild on plugin.csproj
delete plugin.csproj file

Related

In C#, how to `Paket Add` dependencies to all projects in a folder even when they are in separate solutions?

Say I have a packet.dependencies file in a root folder full of different solutions adding up to hundreds of projects, each with a paket.references file.
Is there an easy way to go about adding the same package/same version in all the projects with a single command (or close) with paket?
In my use case, I'm trying to add an analyzer to every C# project we have. It would be tedious to add the same package and version to hundreds of different C# projects...
It was actually just paket add <package ID>, if ran in the root folder with the paket.dependencies file, it will actually find all the .csproj files and add the dependency.
It was the following line in the docs that threw me off:
By default packages are only added to the solution directory, but not on any of its projects. It's possible to add the package to a specific project:
But it will actually add the dependency to all solutions and projects.

Modifying Project Dependency Programatically

Is there a way to add project dependency programmatically? For some reason the project in my solution file the project dependency is not set. What I am thinking of
Open the file and load it as xml document
Traverse through the references . Get the names of the dependency
Get the guid of those project reference
Prepare the project dependency section element
Modify the file by adding this section
Do the same for other 60+ projects
If I am not wrong we can do this by using MSBUILD classes as well .
Any better suggestions ?
On the same line I need to modify the path of one dll in all these project . I don’t want to do it manually .
Eventually I wrote a utility which reads the csproj and sln file as string[] and using Loops/Linq updated the lines and then wrote it back System.IO
Also JetBrains and MSBuild engine has class to find the dependency of a project , what dll its refrerencing etc etc.
If anyone needs help with this then let me know

Having a library as a submodule in combination with a Unity game engine project

I have created a library, with its own git repo. I want to include it in a Unity3D project, but I also want to be able to adjust the library from within the working solution.
Context
Unity
Unity automatically (re-)creates its .sln and .csproj files, so
I can't set the library .csproj as a reference there. In order to use a DLL with Unity, it has to be put in a special "Plugins" folder and will then be included in the auto-generated files.
it's impractical to use Unity's auto-generated .sln for... well, anything other than the Unity project itself.
Library
The library has its own git repo, included as a git submodule. I understand that I can change the output path of mylib.csproj to point to that Unity "Plugins" folder, but then that would be saved in the library git repo - which would make the whole repo moot by having it only work for this project.
Current State
I put the library and Unity project inside a "master solution" and currently have the following structure for that:
-mylib (solution folder, but also a file system folder containing the git submodule)
-mylib.csproj
-unittests.csproj (for mylib)
-Unity (solution folder, but also a file system folder containing the Unity project)
-Assembly-CSharp.csproj
-etc., all the auto-(re-)generated files
-unittests.csproj (for the Unity project)
Goal
What I want to achieve is being able to build mylib.csproj and have its DLL automatically be put into that "Plugins" folder in the Unity project. Given the restrictions mentioned in the "Context" part, is this possible?
I am currently using Visual Studio Community 2017 to set this up, but it has to be possible to work on the end product with other IDEs, especially JetBrains Rider.
Avoid library and Unity .csproj
I now found a solution, much less involved than I thought it would be.
I added a new, empty project to the master solution - I ended up literally calling it BuildToUpdateLibraries - and then did the following things:
set the output type to "Class library"
This way, the project doesn't need a main method, so we can build without actually having any code at all - a build will just create an empty BuildToUpdateLibraries.dll.
added the mylib project as a reference
This will copy the mylib.dll to the BuildToUpdateLibraries output folder.*
Now we can freely edit the BuildToUpdateLibraries.csproj file and will neither make the libraries unusable elsewhere nor have Unity overwrite it on every rebuild.
Copying to the plugins folder
Now, the one last issue here is that when building, we get more than we want.
There is the useless BuildToUpdateLibraries.dll, but also every .dll mylib depends on*. You might actually need (some of) these, but in my case it was the UnityEngine.dll. That .dll is part of Unity and importing it again probably only leads to problems.
Thus, setting the output folder of BuildToUpdateLibraries to the Unity Plugins folder is not an optimal solution. However, as we can now freely edit the BuildToUpdateLibraries .csproj, we can just add post-build events. I added the following line in the post-build events to copy the file:
xcopy "$(TargetDir)mylib.dll" "$(SolutionDir)Unity\Assets\Plugins\MyLib"
Now when I build BuildToUpdateLibraries, it will first build mylib and then build BuildToUpdateLibraries with the mylib.dll included. Finally, it will copy the file to the Unity plugins folder.
*There is an option to not include a .dll in the output folder, but default behaviour is to copy and you would have to do that for every file.

How to create .dll file from multiple files with different extension

Can I create a single dll file of my project which contain other dependent dlls and some other subfolders which contains file which are not .cs file but use to make calculation in my project.
My project look like this:
Above image first arrow shows reference which comes after adding dll ex. abc.dll.
And arrows 2 and 3 shows folders in my project which contains file which are used in code. And those are not .cs (C# files).
Is it possible to create single dll which contain all this dlls and files in folders so that I can distribute to anyone.
Or is there any other way I have to follow.
Let me suggest
You can use ILMerge to solve combining multiple DLL's into one, found here: http://research.microsoft.com/en-us/people/mbarnett/ilmerge.aspx also found in nuget. For the other items, you can add them as resources: https://support.microsoft.com/en-us/kb/319292
Yes you can make a single interface (ONE DLL) that is using other DLL and your own source code.
But you need to ship other DLLs too with your DLL. Because without it other people will get error when consuming other DLL functions.
You'll have to package up all the dependencies as resources in your project.

VS project referenced from two excluded libraries

I have two versions of my application. The first one use references of library LIB_A, the second one use references of library LIB_B. (LIB_A and LIB_B are in fact to versions of the same product, but they differ from each other, even namespaces are different.There can't be installed two versions in the one machine on the same time).
Sourcecodes of my application in both versions are almost the same so I need to have one solution, that can switch which library to use.
How can I do that?
Since you specified VS2010 in your comment, I'm adding this answer separately, so that users of VS2015 can refer to the other answer, which is a lot cleaner.
In VS2010, you can use source code sharing between the two projects. Let's say that you have created AppA, which is the app project that references LibA, and contains all the sources for the app.
You can create an app project, AppB, that references LibB. It also shares all the sources of AppA. This can be done in one of two ways:
Linking All Sources Manually
In AppB, you can create the same folder structure (if any) as AppA. Right click each subfolder and click Add->Existing Item... Navigate to the corresponding folder of AppA and select all the C# files. Now click on the dropdown to the right of the Add button and select "Add as Link". You'll notice that the added sources have a little "shared" arrow in their icons, and that their paths point back to the original.
Linking All Sources Dynamically
If you have lots of files in AppA, or add/remove files regularly, the previous approach can get tiring. There's another way to do this that involves hand-editing AppB.csproj. Open AppB.csproj and create an ItemGroup that imports all the files from AppA. This code assumes that AppA and AppB are subfolders of the solution folder. If not, change the relative paths appropriately.
<ItemGroup>
<Compile Include="..\AppA\\**\*.cs">
<Link>%(RecursiveDir)%(FileName)%(Extension)</Link>
</Compile>
</ItemGroup>
Now when you open the solution, you will see that AppB's contents match that of AppA. The sources are linked, so AppB's conditional build settings (if any) will apply.
You can also exclude files from being included by adding an Exclude attribute to the Compile tag. See the VS documentation for more details.
The only downside of this approach is that you need to hand-edit the csproj file. Also, if you accidentally delete or move linked files, VS will hard-code the list of linked files into the project. The files themselves will still be linked.
It so happens that Visual Studio 2015 (you can download the Release Candidate, which I've found much more powerful and faster than VS2013) has a feature that is designed for this very purpose - Shared Projects. Here's a Channel9 video that describes it.
A shared project contains source files that are compiled directly into projects that reference it. Let's say a shared project Shared has a file foo.cs, and projects AppA and AppB both reference project Shared, then file foo.cs is compiled directly into AppA and AppB - it uses any conditional settings of those projects. So foo.cs could have code that looks like this
#if APPA
// do something
#elif APPB
// do something else
#endif
So to summarize:
Within a single solution, create a Shared Project with all your app sources.
Create two projects AppA and AppB, that represent the two flavors of your app.
AppA references Shared and Lib_A. AppB references Shared and Lib_B.
If needed, add compile variables that control differences in the sources as described above.

Categories