Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Float
borderblack solid 1px
sideright

Table of Contents
stylenone

This document describes how the new layout of Delta Shell developer projects is defined and how it can be expanded with new products and projects. The Delta Shell Framework is split up into separate NuGet packages that can be imported into C# projects in order to develop plugins for Delta Shell.

...

This is the default way of making a solution and the plugin csprojs that come along. Of course, you can do this in visual studio. The csproj that you add should be a class library, because we are going to make a plugin and the plugin is a dll that will be loaded by Delta Shell. Delta Shell is the application that is going to be booted and it is not recommended to make your own launcher.

Warning

Set your C# projects to the .NET Framework 4 version

...

Code Block
languagexml
<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <config>
    <add key="repositoryPath" value="packages"/>
  </config>
  <packageRestore>
    <add key="enabled" value="True" />
    <add key="automatic" value="True" />
  </packageRestore>
  <packageSources>
    <add key="nuget.org" value="https://www.nuget.org/api/v2/" />
    <add key="TeamcityAuth" value="httpshttp://build.deltares.nl/httpAuth/app/nuget/v1/FeedService.svc/" />
    <add key="Teamcity" value="httpshttp://build.deltares.nl/guestAuth/app/nuget/v1/FeedService.svc/" />
  </packageSources>
  <activePackageSource>
    <add key="TeamcityAuth" value="httpshttp://build.deltares.nl/httpAuth/app/nuget/v1/FeedService.svc/" />
  </activePackageSource>
  <packageSourceCredentials>
    <TeamcityAuth>
      <add key="Username" value="dscbuildserver" />
      <add key="ClearTextPassword" value="[DSCBUILDSERVERPASSWORD]" />
    </TeamcityAuth>
  </packageSourceCredentials>
</configuration>

...

Because we want to make an ApplicationPlugin, we are going to need another package. Install it in the same way via the Package Manager ConsoleInstall-Package DeltaShell.ApplicationPlugin -Version x.x.x.xxxx. To stay consistent, use the same version number.

Infowarning

Make sure that you always use the latest pinned version from TeamCity. Omitting the -Version option will give you the latest successful build, but this is not desired.

Image Added

DeltaShell.ApplicationPlugin

...

The DeltaShell.Framework package ensures that all files in the framework are on your computer. It also adds a .targets fie file to your project so that it will copy the framework files into $(SolutionDir}bin\DeltaShell.

...

You can also make a unit test project that works in Delta Shell. To do so, install the DeltaShell.TestProject package into your test project. Take notice of the Default Project in the Package Manager Console, because you want the DeltaShell.TestProject to be in your test project and not in your application plugin project. The package sets the output directory of your project to $(SolutionDir)\bin\$(Configuration)

The test The test project also adds some extra lines to App.config.These lines make sure that your unit test can find the framework and the plugins.

Code Block
languagexml
<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <probing privatePath="DeltaShell;plugins;"/>
    </assemblyBinding>
  </runtime>
</configuration>

Auto-Restore Packages

You don't have to add the packages folder to svn, because TeamCity and Visual Studio already know how to handle and download the packages.

You may right click on your solution in visual studio and click Enable auto restore NuGet packages. This will add some files and a folder to your solution. From now on, the packages will be downloaded automatically when missing before compilation.

Creating an ApplicationPlugin derivative

Now that your project is ready to work with, you can add your first class, that will be an ApplicationPlugin. How to actually write the rest of an ApplicationPlugin will be explained in another tutorial.

Code Block
languagec#
namespace DeltaShell.Plugins.Unibest
{
    [Extension(typeof(IPlugin))]
    public class UnibestApplicationPlugin : ApplicationPlugin
    {
    }
}

Now you are almost ready to compile.

Setting up compilation

It is super-duper very important to remember the following:

Warning

You must always set the references to framework dll's to copy-local=False. This also accounts for Mono.Addings and other dll's that are automatically added to the project.

Why, you ask? Because they are already being copied into $(SolutionDir)\bin\DeltaShell and don't need to be in your own assembly's output folder.

Warning

You must always set the references to other project to copy-local=False

Why, you ask? Because they already have their own output folder and you don't want these dlls to be doubled in your bin directory.

 

Image Removed

Sometimes, you just need a reference to an external library that is already compiled. You can add those too. But remember that adding a reference comes with the responsibility of copying it or not.

If you require other files, like native libraries that are not referenced, to go to your output folder; add them as content to the project. The folder structure that is used in the project is mirrored to the output folder. For example, if you have a folder called myNatives in your csproj, there will be a folder called myNatives next to the final dll. Set the content that you want to add to Copy if newer, so that it will be copied to the output folder.

 

 

Now you may press the compile button. Have a look in your bin folder next to your solution folder. You will see that there are two folders. One is for the framework, the other contains all the plugins.

Verify your build output

You can find your own dll in bin\$(Configuration)\plugins\$(AssemblyName).

Your test project is compiled into the bin folder directly, because it has to know about the plugins and the framework. This may look a bit odd, but we are still looking for a good workaround for that. There will also be a folder called test-data that contains a symbolic link. This will be explained later in this tutorial.

...

Updating to a newer version

If you have received a message that a new version of the framework has been released, you can manually update your packages in your product by executing some NuGet commands via the NuGet Package Console, which can be found under Tools > NuGet package manager. Do not forget to set your package source to TeamcityAuth.

Code Block
Update-Package DeltaShell.ApplicationPlugin -Version y.y.y.yyyyy -FileConflictAction Overwrite
Update-Package DeltaShell.TestProject -Version y.y.y.yyyyy -FileConflictAction Overwrite
Update-Package DeltaShell.Framework -Version y.y.y.yyyyy -FileConflictAction Overwrite

This will uninstall the old version and then install the new version. You can simply commit the files that have been changed in your projects. You don't have to commit the nuget packages, because we already have auto-restore enabled.

When you are going to commit the updated package, you can verify your commit. There are a couple of files that have changed. Namely, everything that has the version number referenced in their file. So for example, all csproj files will have updated references. Another file is the packages.config file that belongs to the project. It will contain an updated version number as well. All files that were in the content folder of the nuget package are replaced.

Old

New

csproj

Code Block
languagexml
<ItemGroup>
  <Reference Include="DelftTools.Functions">
    <HintPath>..\..\packages\DeltaShell.Framework.1.0.4.33577\lib\net40\DeltaShell\DelftTools.Functions.dll</HintPath>
    <Private>False</Private>
  </Reference>
</ItemGroup>

csproj

Code Block
languagexml
<ItemGroup>
  <Reference Include="DelftTools.Functions">
    <HintPath>..\..\packages\DeltaShell.Framework.1.0.5.33698\lib\net40\DeltaShell\DelftTools.Functions.dll</HintPath>
    <Private>False</Private>
  </Reference>
</ItemGroup>

packages.config

Code Block
<?xml version="1.0" encoding="utf-8"?>
<packages>
  <package id="DeltaShell.ApplicationPlugin" version="1.0.4.33577" targetFramework="net40" />
  <package id="DeltaShell.Framework" version="1.0.4.33577" targetFramework="net40" />
  <package id="log4net" version="1.2.10" targetFramework="net40" />
  <package id="Mono.Addins" version="1.0" targetFramework="net40" />
  <package id="PostSharp" version="2.1.7.28" targetFramework="net40" />
</packages>

packages.config

Code Block
<?xml version="1.0" encoding="utf-8"?>
<packages>
  <package id="DeltaShell.ApplicationPlugin" version="1.0.5.33698" targetFramework="net40" />
  <package id="DeltaShell.Framework" version="1.0.5.33698" targetFramework="net40" />
  <package id="log4net" version="1.2.10" targetFramework="net40" />
  <package id="Mono.Addins" version="1.0" targetFramework="net40" />
  <package id="PostSharp" version="2.1.7.28" targetFramework="net40" />
</packages>

Creating an ApplicationPlugin derivative

Now that your project is ready to work with, you can add your first class, that will be an ApplicationPlugin. How to actually write the rest of an ApplicationPlugin will be explained in another tutorial.

Code Block
languagec#
namespace DeltaShell.Plugins.Unibest
{
    [Extension(typeof(IPlugin))]
    public class UnibestApplicationPlugin : ApplicationPlugin
    {
    }
}

Now you are almost ready to compile.

Setting up compilation

It is of utmost importance to remember the following:

Warning

You must always set the references to framework dll's to copy-local=False. This also accounts for Mono.Addings and other dll's that are automatically added to the project.

Why, you ask? Because they are already being copied into $(SolutionDir)\bin\DeltaShell and don't need to be in your own assembly's output folder.

Warning

You must always set the references to other project to copy-local=False

Why, you ask? Because they already have their own output folder and you don't want these dlls to be doubled in your bin directory.

 

Image Added

Sometimes, you just need a reference to an external library that is already compiled. You can add those too. But remember that adding a reference comes with the responsibility of copying it or not.

If you require other files, like native libraries that are not referenced, to go to your output folder; add them as content to the project. The folder structure that is used in the project is mirrored to the output folder. For example, if you have a folder called myNatives in your csproj, there will be a folder called myNatives next to the final dll. Set the content that you want to add to Copy if newer, so that it will be copied to the output folder.

 

 

Now you may press the compile button. Have a look in your bin folder next to your solution folder. You will see that there are two folders. One is for the framework, the other contains all the plugins.

Warning

If something went wrong during compilation and you see that your bin folder contains more than you wanted, it is the easiest and cleanest to just delete your bin folder in the solution folder. This is quicker and safer than pressing clean in Visual Studio.

Verify your build output

You can find your own dll in bin\$(Configuration)\plugins\$(AssemblyName).

Your test project is compiled into the bin folder directly, because it has to know about the plugins and the framework. This may look a bit odd, but we are still looking for a good workaround for that. There will also be a folder called test-data that contains a symbolic link. This will be explained later in this tutorial.

Info

Always take notice that your plugin folder only contains the dlls you expect. And always take notice that $(SolutionDir)bin\$(Configuration) only contains test dlls and test utils dlls.

The bin folder should look like the following. The test dlls are directly in the Debug or Release folder and finds the dlls via app.config probing. The plugin dlls are in its plugin directory and should not contain any dlls like PostSharp or other 3rd party dlls. And there shouldn't be any deltashell framework dlls either.

Image Added

Debugging Delta Shell

Since your assemblies are just dll's and don't have an actual startup point, you will have to set it yourself. We wanted to add this information in the install script of the NuGet packages, but it seems that this is information found in the .suo file.

  1. Pick any application plugin as Startup Project
  2. Set it as startup project
  3. Make sure you have compiled the project
  4. Go to the Debug settings of the project
  5. Set the Start Action to Start external program and browse to bin\Debug\DeltaShell\DeltaShell.Gui.exe.
  6. Now you can press F5.

Image Added

...

Unit Test Data

Your unit test project is actually already set up correctly when you have followed the steps explained above. There is just one last thing when you want to add test data. We don't want to copy over the unit test data every time we are going to compile the project. So what can you do to avoid that? Add your test data in a folder next to the testcsproj called test-data. A post-build event has been added to your testcsproj when you installed DeltaShell.TestProject. This post-build event creates a symbolic link to your test-data folder and you can access it via TestHelper.GetDataDir().

...

We have already set up a couple of templates in teamcity for you to automatically let your unit tests run and let your installers create what it needs to.

  • Run Product Tests
  • Run Product Tests Updated Trunk
  • Build Solution (Release)
  • Build MSI via MSBuild

Run Product Tests

Make a new TeamCity configuration and make it based on the template for unit tests. Fill in the name of your sln file in product_sln_file. You may exclude or include some categories if you want.

...