0

I'm busy creating a Nuget package that will be used internally only which installs other packages being dependencies, Ninject being one of them.

After installation, a NinjectWebCommon.cs file is added to the App_Start folder of the project. My custom package requires that file to be modified in the following way: (only showing part of the code)

//code above removed... 
using Ninject;
using Ninject.Web.Common;
//modified this part already - refer to block quote 1 on how i did it
using mylibrary.whatever;
//code below removed...

I managed to insert the line "using mylibrary.whatever" by using install.ps1 (as per the Nuget package convention) in the following way, albeit not that sophisticated (VERY little experience with powershell):

Blockquote 1:
$p = get-project;
$p = Split-path $p.filename;
$p += "\App_Start\NinjectWebCommon.cs";
(Get-Content $p) | foreach-object {$_ -replace "using Ninject.Web.Common;", "using Ninject.Web.Common;`r`n using mylibrary.whatever;"} | Set-Content $p;

Now that's quite ok for a 1 line addition.

My problem comes in with changing this section...

// code above removed...
private static void RegisterServices(IKernel kernel)
{
}
// code below removed...

to this...

// code above removed...
private static void RegisterServices(IKernel kernel)
{
    kernel.Load(new mylibrarymodule());
}
// code below removed...

To complicate things a little more, this NinjectWebCommon.cs file could be changed in the same manner by x amount of internal Nuger packages. So

// code above removed...
private static void RegisterServices(IKernel kernel)
{
    kernel.Load(new mylibrarymodule());
}
// code below removed...

could also become

// code above removed...
private static void RegisterServices(IKernel kernel)
{
    kernel.Load(new mylibrarymodule());
    kernel.Load(new myotherlibrarymodule());
    kernel.Load(new anotherlibrarymodule());
}
// code below removed...

Any help would be appreciated as powershell is not one of my strong points...

3 Answers 3

2

Managed to eventually sort this out in my install.ps1 with a lot of T&E:

install.ps1 in my Nuget Package:

#Get the file:
$p = get-project;
$p = Split-path $p.filename;
$p += "\App_Start\NinjectWebCommon.cs";

# Do the first insert
$regex = new-object Text.RegularExpressions.Regex "using Ninject.Web.Common;", ('singleline');

set-content $p $regex.Replace((get-content $p) -join "`n", "using Ninject.Web.Common;`n`tusing mylibrary.whatever;")

# Do second insert
$regex = new-object Text.RegularExpressions.Regex "private static void RegisterServices\(IKernel kernel\)\s*\{", ('singleline','multiline');

set-content $p $regex.Replace((get-content $p) -join "`n", "private static void RegisterServices(IKernel kernel)`n`t`t{`n`t`t`tkernel.Load(new myclass_in_mylibrary.whatever());")

Credit to:

Matt Ward's answer here and
Stej's answer here

The next challenge is to allow a complete uninstallation of the file once it's been edited as Nuget doesn't allow an uninstallation if the file was modified... *sigh...

Sign up to request clarification or add additional context in comments.

Comments

0

I'm quite new to ps as well and had to do some search and testing to come up with this:

$fileName="C:\tmp\YourFileName"
$searchString="Primary search string here" #In your case it's: "private static void RegisterServices(IKernel kernel)"
$searchStrFound=0

(Get-Content $fileName) | 
Foreach-Object {
    #Send each line to output
    $_
    if ($_ -match $searchString)
    {
        #We found the actual search string
        $searchStrFound=1
    }
    if ($searchStrFound=1 -And $_ -match "\{")
    #If search string is already found and current line is {
    {
        "Insert your text here"
        "Insert Line 2 here"
        "Insert whatever here..."
        $searchStrFound=0 #Reset value to 0 so that you won't change anything else
    }
} | Set-Content $fileName

I tried this with your

// code above removed...
private static void RegisterServices(IKernel kernel)
{
}
// code below removed...

example and it worked just fine.

I hope it helps

/ut

1 Comment

Thanks for the answer @uTe1sT but it adds multiple inserts in the full file. You can test this by installing the Ninject.web packet and try to perform this on the NinjectWebCommon.cs file in the App_Start directory. I did manage to get a working solution yesterday and answer added for some1 else's needs... It would be interesting to see your workable version as I didn't know how the | solution worked until now, thanks for that! :-)
0

I would actually recommend the other way around: do not overwrite that file, create your own MyNinjectBindings and thru a readme file instruct the developer to add the call manually to your code so it registers your bindings.

This way, if your package is updated, MyNinjectBindings will also get updated but the custom code the developer may have added to NinjectWebCommon.cs remains there.

It is a less intrusive way and more flexible, my opinion.

Thanks

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.