JsonStatham
JsonStatham

Reputation: 10374

Creating a conditional NuGet package

I have created a custom assembly in C# which is going to be used by a number of different existing systems, there is quite a lot of configuration involved in getting this assembly working with our systems so to make things easier, we decided to create a local NuGet Server and roll the assembly into a NuGet package.

This worked perfectly well and we were able to add all the dependencies the assembly requires and add a web.config.transform file to merge in any additional nodes required.

This is where we hit our first stumbling block...

Firstly as I mentioned previously the assembly is written in C#, the application we are test running is written in VB.Net. As we are using log4net in the assembly we have implemented WebActivatorEx to ensure this was initialised on application startup, meaning we have an AppStart class which sits App_Start folder. However, after referring to the WebActivatorEx documentation we noticed that if the project is a website as apposed to a web application the AppStart class must sit inside the App_Code folder not the App_Start folder and must also use the PostApplicationStartMethod and not the PreApplicationStartMethod.

Also as the AppStart class is written in C# and will sit inside a VB.Net project we need this converting to VB only if the target project is VB to avoid messing around with more configuration files which is something we are trying to minimise.

In short, the main questions here are:

  1. Can our NuGet package have some sort of conditional behaviour, i.e. if its a VB.Net project add the AppStart class in VB.Net and if its C#, leave it as C#.

  2. If the project is a website place this AppStart class in the App_Code folder and use the PostApplicationStartMethod, if the project is a web application place the AppStart class in the App_Start folder and use the PreApplicationStartMethod.

  3. Is this even the correct approach in terms of initialising log4net without re-writing the target application's global.asax

  4. I'm aware you can run PowerShell commands inside the NuGet package, is there anyway of using this to work out whether the project is C# || VB or am I complicating things and should I simply create 4 different NuGet packages for each and every scenario but this seems plain wrong.

I will await and welcome any suggestions or comments.

Upvotes: 4

Views: 1923

Answers (2)

Yishai Galatzer
Yishai Galatzer

Reputation: 8862

Assuming the user is not modifying the appstart code you can just put the appstart code in a compiled assembly, that would avoid the vb.net vs. c#.

I'm also not sure why you need to use the PostApplicationStart vs. the PreApplicationStart. This is not an inherent difference between Web Site vs. Web application, you might want to look deeper into this. It's probably an ordering thing in the implementation of your specific Web Site.

Upvotes: 3

Goyuix
Goyuix

Reputation: 24370

It sounds like you will need to leverage the Init.ps1 and Install.ps1 support in NuGet. From their documentation:

  • Init.ps1 runs the first time a package is installed in a solution
  • Install.ps1 runs when a package is installed in a project.
    • $project is a reference to the EnvDTE project object and represents the project the package is installed into.

You should be able to use those scripts, and the specifically the special variable $project to determine the type of project you are installing your package into and make the appropriate adjustments to the project code. You can also use the helper cmdlet Get-Project in the Package Manager Console to get a reference to the EnvDTE object that will be passed to your Install.ps1 script. That should help in looking at the different properties and build up your conditional logic.

For example:

PM> $p = Get-Project
PM> $p.Type
C#

Reference: http://docs.nuget.org/docs/creating-packages/creating-and-publishing-a-package#powershell

Upvotes: 2

Related Questions