Showing posts with label NuGet. Show all posts
Showing posts with label NuGet. Show all posts

Thursday, January 28, 2016

Introducing SharePoint Package Manager

Introduction

Half a year ago, I announced – in this post – the forthcoming release of a new secret weapon.  I apologize for the delay, but I entertained myself doing other things and I couldn't find a way to spend a couple of days on formulating it.

I could even tell you: ‘I had no time to do it’, but I learned the lesson – maybe I'm still learning – from my father. He always insisted me: ‘Alex, the time is the same’. So, what actually happened was a matter of time management and prioritization.

The true is, I also expected that something like this already exists at this time, but it doesn’t. So, I recalled this, wrote the minimal working code, push the sources and here it is.


What is SharePoint Package Manager? 

SharePoint Package Manager
The SharePoint Package Manager is a NuGet-based distribution and deployment system for SharePoint's solutions.

Basically, it's an extension of the SharePoint Central Administration site that automates the process for install or update solution packages from package sources (regular NuGet repositories).

Why NuGet?

Why not? NuGet is the widely accepted and popular package manager among .net developers.

There are also a lot of custom solutions and initiatives that use NuGet as the backend, for instance, ReSharper extension manager, OctopusDeploy, Chocolatey, Squirrel, you know, even Catel extending the modularity options of Prism.


There are only a few rules in order to use this package manager, starting with this 'new' concept: solution package.

What is a solution package?

A solution package is a regular NuGet package with its name ending in '.wsp' and with following structure:
A sample of solution package for SignalR.
Notice how the folder 'content' contains a wsp file with the same name of the solution package and that’s it.

A solution package can also have declared dependencies, but only between solution packages.

Maybe the naming convention looks weak, but there is only one package in the gallery with name Digst.OioIdws.Wsp, so, for me, is enough. Eventually, the package manager could also track non-solution packages through an ignore list.
Solution packages from NuGet Gallery. The Digst.OioIdws.Wsp isn't a solution package.

Managing package sources

The SharePoint Package Manager includes a page to manage the package source. You are able to add, remove, edit, enable or disable a package source.

Creating a new package source


The default package source is the NuGet Gallery.

Installing or updating solution packages

The SharePoint Package Manager also includes a page to manage the farm packages. Looking for the installed solutions in the SharePoint solution storage and making a join with available solution packages from the package sources, the page shows the available solution packages to install or update.

Managing the farm packages
Sorry about the name of the solution package in Spanish on the image above but was client choice and the picture was taken from real life scenario.

The SharePoint Package Manager provides an option to install or update solution packages. After clicking the button – on the right of the solution package info – the system will schedule a job to install or update the last available version of the selected solution package. If the selected package has dependencies, the package manager will also install or update all dependencies in the right order.

Tracking the install or update process.

What's next?

This is almost a draft or a proof of concept, remember just the minimal working code. So, you can try. I also published the SignalR.SharePoint.WSP solution package at NuGet gallery, so, you should see it as an available solution package.

Enjoy it, and let me know what you think. Even better, we can do this together, just fork the source on GitHub. There are a lot of things to do, including better user interface, REST services, a better approach for settings storage, ignore list, performance issues, msbuild extension, Visual Studio extension, and so on. You tell me.

In the meantime, I’m already working to turn more Catel’s rumors in true.

Talking about rumors, if everything goes right, I might update my resume in about seven months. Yes, your assumption is correct, I'm a father candidate ;).

Friday, February 21, 2014

Developing a ReSharper Plugin – The backward compatibility approach

Introduction

We have being developed a ReSharper plugin for Catel framework also known as CatelR# for a while, following an interesting approach in order support the new R# version and also keep the backward compatibility.

If you want to know how we made it, just take a look.

Visual Studio solution setup

1)    Create project per supported R# version, which means that the output of each project is targeting to the specific version of R# and references the specific version of the SDK.



2)    Keep in mind, that could be several breaking changes between R# SDK versions, but nothing that couldn’t be handled with pre-processor directives.

#if R70 || R71 || R80
        protected override void Process(CSharpGeneratorContext context)

#elif R61
        public override void Process(CSharpGeneratorContext context)
#endif
        {
            CSharpElementFactory factory = CSharpElementFactory.GetInstance(context.Root.GetPsiModule());
#if R80
            IDeclaredType viewModelToModelAttributeClrType = TypeFactory.CreateTypeByCLRName(CatelMVVM.ViewModelToModelAttribute, context.PsiModule, UniversalModuleReferenceContext.Instance);
#else
            IDeclaredType viewModelToModelAttributeClrType = TypeFactory.CreateTypeByCLRName(CatelMVVM.ViewModelToModelAttribute, context.PsiModule);
#endif
            /*...*/
#if R80
                        var fixedArguments = new List<AttributeValue> { new AttributeValue(ClrConstantValueFactory.CreateStringValue(model.ShortName, context.PsiModule, UniversalModuleReferenceContext.Instance)) };
#else
                        var fixedArguments = new List<AttributeValue> { new AttributeValue(ClrConstantValueFactory.CreateStringValue(model.ShortName, context.PsiModule)) };
#endif
                        if (propertyName != modelProperty.ShortName)
                        {
#if R80
                            fixedArguments.Add(new AttributeValue(ClrConstantValueFactory.CreateStringValue(modelProperty.ShortName, context.PsiModule,  UniversalModuleReferenceContext.Instance)));
#else
                            fixedArguments.Add(new AttributeValue(ClrConstantValueFactory.CreateStringValue(modelProperty.ShortName, context.PsiModule)));
#endif
                        }
            /*...*/
                    }
                }
            }
        }

3)    Keep all these entire project sources synchronized. Could be very easy thanks to Caitlyn.




4)   Finally redirect the build projects outputs to dealing with ease with the packaging of the deployment units.

Building the deployment units

The R# plugin build process indeed an heterogeneous one as any build process. Even though  this build could be handled via msbuild tasks, we actually recommend the usage of tools with intuitive GUI in order to quickly creating and debugging such build "scripts", such as FinalBuilder or VisualBuild.


1) Since 8.0 R# version  the NuGet based extension manager is available. Therefore one of the build output could be a NuGet package to distribute your plugin through the ReSharper extension gallery.

2) But NuGet based extension manager is not available for all R# versions. Therefore a second build output could also be classic deployment unit built on top of any of the existing installer system.  For instance InnoSetup or NSIS.

The following are the code snippets from the install and uninstall sections of CatelR# setup. Notice how we deal with build output to support all R#  versions.


# ...
# Installer section
# ...

Push "v6.1"
Push "v7.0"
Push "v7.1"
Push "v8.0"
Push "v8.1"
${Do}
  Pop $0
  ReadRegStr $1 HKLM "Software\JetBrains\ReSharper\$0" InstallDir
  ${If} $1 != ''
    DetailPrint "Installing Catel.ReSharper for JetBrains ReSharper $0"
    SetOutPath "$1\Plugins\$(^Name)"
    ${If} $0 == 'v6.1'
      File /r "..\..\output\Debug\v6.1\*.dll"
    ${ElseIf} $0 == 'v7.0'
      File /r "..\..\output\Debug\v7.0\*.dll"
    ${ElseIf} $0 == 'v7.1'
      File /r "..\..\output\Debug\v7.1\*.dll"
    ${ElseIf} $0 == 'v8.0'
      File /r "..\..\output\Debug\v8.0\*.dll"
    ${ElseIf} $0 == 'v8.1'
      File /r "..\..\output\Debug\v8.1\*.dll"
    ${EndIf}
    Push true
    Pop $3
    WriteRegStr HKLM "${REGKEY}" "$0" 1
  ${EndIf}
${LoopUntil} $0 == "v6.1"

# ... 

# ... 
# Uninstaller section
# ... 

Push "v6.1"
Push "v7.0"
Push "v7.1"
Push "v8.0"
Push "v8.1"
${Do}
  Pop $0
  ReadRegStr $1 HKLM "${REGKEY}" "$0"
  ${If} $1 == '1'
    ReadRegStr $2 HKLM "Software\JetBrains\ReSharper\$0" InstallDir
    ${If} $2 != ''
      RMDir /r /REBOOTOK "$2\Plugins\$(^Name)" 
      DeleteRegValue HKLM "${REGKEY}" "$0"
    ${EndIf}
  ${EndIf}
${LoopUntil} $0 == "v6.1"  

# ...


Conclusions

Just a few minutes ago, I read the notification about the release of R#8.2 EAP. It’s a good moment to revalidate this approach. Let’s see,… creating a new project with post-fix 82, …installing the SDK package, ..., ...time out, sorry…slow connection…,…,…,..updating the build script, …, …, … reviewing for breaking changes, good news, there are no breaking changes,… updating setup script…., committing source modifications, … running the build script and it’s done.

Now you can update the extension from the extension gallery or download the full installer of CatelR# with support for R#8.2 EAP ;)

Tuesday, October 22, 2013

Catel extends Prism modularity options through NuGet

Introduction


Prism provides a lot of options regarding modularity by default. Fact is that most of the stuff  you need to build a modularized application is available on Prism. Prism contains several modularity options including ways to retrieve modules from a directory, set them up through the configuration file, and even options to create modularized Silverlight applications.

On the other hand, Catel provides support for module catalog composition in order to enable more than one modularity options into a single application.

Nowadays, initiatives around NuGet come from everywhere, such as Shimmer with the same goal of ClickOnce (but works), OctopusDeploy for release promotion and application deployment or even the recently released extension manager of ReSharper 8.0.

So, the Catel team comes with a new one and the fact is that we wondered why no one told about this before: 

What if you would be able to distribute your application's modules through NuGet?

If you want to know how, take a look.


Enabling NuGet based modularity option


With the forthcoming 3.8 version of Catel you will be able to install and load modules from a NuGet repository. The only thing you have to do is:
  1. Write a module as you know with Prism (or better in combination with Catel).
  2. Create a NuGet package for the module and publish it into your favorite gallery.
  3. Use and configure the NuGetBasedModuleCatalog in the application’s bootstrapper.
The first two steps are well documented. For details see creating and publishing a package and declaring modules from NuGet and Catel documentation.


So, now we can focus on the third one.

Use and configure the NuGetBasedModuleCatalog in the application’s bootstrapper


In order to simplify the following explanation we published a package into the official NuGet Gallery named Catel.Examples.WPF.Prism.Modules.NuGetBasedModuleA. Such package contains an assembly with a single class like this one:
 
public class NuGetBasedModuleA : ModuleBase
{
    public NuGetBasedModuleA(IServiceLocator container):base("NuGetBasedModuleA", null, container)
    {
    }

    protected virtual void OnInitialized()
    {
      var messageService = this.Container.ResolveType<IMessageService>();
      messageService.Show("NuGetBasedModuleA Loaded!!");
    }
}

Let’s start writing an  application that will use this public packaged module. Indeed, the main point of interest here is about the usage and configuration of the NuGetBasedModuleCatalog. Therefore just write the bootstrapper as follow:

public class Boot : BootstrapperBase<MainWindow, NuGetBaseModuleCatalog>
{
  protected override void ConfigureModuleCatalog()
  {
    base.ConfigureModuleCatalog();
    this.ModuleCatalog.AddModule(new ModuleInfo 
          { 
               ModuleName = "NuGetBasedModuleA", 
               ModuleType = "Catel.Examples.WPF.Prism.Modules.NuGetBasedModuleA.NuGetBasedModuleA, Catel.Examples.WPF.Prism.Modules.NuGetBasedModuleA", 
               Ref = "Catel.Examples.WPF.Prism.Modules.NuGetBasedModuleA, 1.0.0-BETA", 
               InitializationMode = InitializationMode.OnDemand
          });
  }
}

Notice how the Ref property of ModuleInfo is used to specify the package id and optionally the version number. If the version number is not specified then the application always will try to download the latest version keeping the modules up to date.

Finally, to make this demo work, just put in the XAML of the main window the ModuleManagerView control, run


and click the check box.

Conclusions


Yes, we did it again. Catel keeps working alongside Prism. Now, we extended Prism’s modularity options through NuGet in order to provide a powerful mechanism of application module distribution. 

If you want to try, just get the latest beta package of Catel.Extensions.Prism and discover by yourself all scenarios that you can handle with this Catel exclusive feature.

Saturday, September 28, 2013

Keep updated CatelR# with ReSharper 8.0



CatelR# is now compatible with the latest version of ReSharper (R#).

We also keep the compatibility with the most recent R# versions including 6.0, 7.0 and 7.1. The full installer, that also includes the R# 8.0 assemblies, of the latest beta of CatelR# is available to download here.

R# 8.0 includes a NuGet based Extension Manager and the Catel Team started to publish the CatelR# extension in the Extension Gallery.

Yes, CatelR# is alive. We keep working in more features and also are waiting for your ideas. You got one? Let us know!

So, ensure yourself to install the latest version of R# and you will no miss any of the forthcoming CatelR#'s cool features.

X-ray StoneAssemblies.MassAuth with NDepend

Introduction A long time ago, I wrote this post  Why should you start using NDepend?  which I consider as the best post I have ever...