更新并发布一个NuGet 组件-外加使之更智能并避免用WebActivator 编辑源

[原文发表地址] Updating and Publishing a NuGet Package - Plus making NuGet packages smarter and avoiding source edits with WebActivator

[原文发表时间] 2011-02-17 11:57 PM

几天前我写过一个叫做“用简单7步创建一个NuGet 组件 -外加使用NuGet把ASP.NET MVC 3整合进已有的Web窗体应用程序中去”的帖子。标题很长是吧?我想是的。

这个帖子有两个作用:首先,是向大家展示创建一个NuGet组件是多么地容易(并鼓励你自己也来试试)第二是与你分享一些试验,在文件|新解决方案后启用新的/有趣的功能。在那个例子中,我们已有一个ASP.NET WebForms应用程序,然后通过一行就加入了ASP.NET MVC,使之成为一个简易的混合应用程序。

install-package AddMvc3ToWebForms

恩,并不是真正只有一行。在 AddMvc3ToWebForms 组件的0.5 中,你仍然需要自己在Global.asax里将Areas, Routes 与 Filters衔接起来。我实现了一个辅助方法,另用一行来完成上述事情,但是它还是有些不给力。

现在,本帖子也有两个作用:首先,展示如何创建一个组件的更新,以及对消费者来说更新过程是怎么样的。第二,展示你如何(以及为什么)在制作组件的时候再多花点功夫,让用户可以“轻松更新”。

对一个NuGet 组件创建一个更新(升级)

步骤1- 更新(升级) NuSpec文件

我打开AddMvc3ToWebForms.nuspec文件,并将版本改变了一档至0.6. 同时我添加了一个依赖项--另一个叫做WebActivator的NuGet组件,我打算使用它来使我的组件能工作起来,还不用额外代码行。WebActivator需要是 1.1或更高版本,因为这些版本才有一个我需要的特定功能。

<?xml version="1.0"?>

 

<package xmlns:xsd="https://www.w3.org/2001/XMLSchema" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance">

 

  <metadata xmlns="https://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">

 

    <id>AddMvc3ToWebForms</id>

 

    <version>0.6</version>

 

    <authors>Scott Hanselman</authors>

 

    <owners>Scott Hanselman</owners>

 

    <iconUrl>https://www.hanselman.com/images/nugeticon.png</iconUrl>

 

    <requireLicenseAcceptance>false</requireLicenseAcceptance>

 

    <description>A totally unsupported way to quickly add ASP.NET MVC 3 support to your WebForms Application. Works on my machine.</description>

 

    <tags>MVC MVC3 ASP.NET WebForms</tags>

 

    <dependencies>

 

      <dependency id="WebActivator" version="1.1" />

 

    </dependencies>

 

  </metadata>

 

</package>

步骤2-作出新的改动

当引进多个NuGet组件时,通常人们想要在应用程序启动时运行一些东西。比如是设置一些上下文、连接字符串, 软件工厂的默认设置,或是依赖项解析器。有不少组件都需要这些功能,David Ebbo创建了WebActivator组件以使之更为容易。它正式地封装了"PreApplicationStartMethod"这一ASP.NET 4新的属性,David还启用了PostApplicationStartMethod。

在我新版的AddMvc3ToWebForms组件里,我创建了一个叫做AppStart_RegisterRoutesAreasFilters.cs.pp的新文件。注意.pp扩展,它向NuGet发出信号来预处理文件并且替换像$rootnamespace$这样的标志,有点像一个迷你-迷你-代码-生成器。

剩余的应该看上去很熟悉:我们注册Areas, GlobalFilters 及Routes。非正式命名规则是给类和文件加上AppStart_前缀,以便包含有添加了AppStart_*.*的组件的项目会将这些文件放在一起。

using System;

 

using System.Collections.Generic;

 

using System.Linq;

 

using System.Web;

 

using System.Web.Mvc;

 

using System.Web.Routing;

 

using Microsoft.Web.Infrastructure;

 

[assembly: WebActivator.PostApplicationStartMethod(typeof($rootnamespace$.AppStart_RegisterRoutesAreasFilters), "Start")]

 

namespace $rootnamespace$ {

 

    public static class AppStart_RegisterRoutesAreasFilters {

 

        public static void Start() {

 

            // Set everything up with you having to do any work.

 

            // I'm doing this because it means that

 

            // your app will just run. You might want to get rid of this

 

            // and integrate with your own Global.asax.

 

            // It's up to you.

 

            AreaRegistration.RegisterAllAreas();

 

            RegisterGlobalFilters(GlobalFilters.Filters);

 

            RegisterRoutes(RouteTable.Routes);

 

        }

 

        public static void RegisterGlobalFilters(GlobalFilterCollection filters)

 

        {

 

            filters.Add(new HandleErrorAttribute());

 

        }

 

        public static void RegisterRoutes(RouteCollection routes)

 

        {

 

            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

 

            routes.MapRoute(

 

                "Default", // Route name

 

                "{controller}/{action}/{id}", // URL with parameters

 

            new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults

 

            );

 

        }

 

    }

 

}

注意这行

[assembly: WebActivator.PostApplicationStartMethod(typeof($rootnamespace$.AppStart_RegisterRoutesAreasFilters), "Start")]

David添加了"PostApplicationStart"选项,因为在PreApplicationStart 里注册Areas太早了。因此对于我的组件,我想让这些在App_Start之后运行。这都是新玩意儿,还正处于开发之中。因此如果你有什么想法、改进或强烈的意见尽可以与David分享

步骤3-建立一个新的NuPkg文件

从命令行, 运行…

NuGet pack

…你会自动获得一个新文件,就像这个截图一样:

clip_image003

步骤4-在https://nuget.org上发布这个更新(或者任何NuGet服务器或文件共享)

我可以登陆我的账户从浏览器界面里上传文件,但是我可能会在各处改来改去,所以从命令行来发行会比较好。

我从这个站点获取API 密钥…clip_image005

..并使用它从命令行发布(使用我神奇的pulish.bat)内容如下:

nuget push AddMvc3ToWebForms.0.6.nupkg e5c2bbe6-xxxx

…以及结果..

C:\AddMvc3ToWebForms>nuget push AddMvc3ToWebForms.0.6.nupkg e5c2bbe6-xxxx
Creating an entry for your package [ID:AddMvc3ToWebForms Ver:0.6]...
Your package was uploaded to the server but not published.
Publishing your package [ID:AddMvc3ToWebForms Ver:0.6] to the live feed...
Your package was published to the feed.

现在我已就绪。我已经得到了version 0.6 live now。那么给这个库的用户体验又是什么呢?

获得一个NuGet 组件的更新
有两种方法来找出我的项目正使用什么NuGet 组件并更新它们。

组件管理控制台

从组件管理控制台我可以键入Get-Package...

PM> Get-Package
Id Version Description
-- ------- -----------
AddMvc3ToWebForms 0.5 A totally unsupported

看上去我好像有了版本0.5.我可以这样来更新它

PM> Update-Package AddMvc3ToWebForms
'WebActivator (≥ 1.1)' not installed. Attempting to retrieve dependency from source...
Done.
Successfully installed 'WebActivator 1.1.0.0'.
Successfully installed 'AddMvc3ToWebForms 0.6'.
Successfully removed 'AddMvc3ToWebForms 0.5' from WebApplication7.
Successfully uninstalled 'AddMvc3ToWebForms 0.5'.
Successfully added 'WebActivator 1.1.0.0' to WebApplication7.
Successfully added 'AddMvc3ToWebForms 0.6' to WebApplication7.

注意NuGet自动地移除了AddMvc3ToWebForms 0.5并安装了AddMvc3ToWebForms 0.6。它同时自动地加入了依赖项在WebActivator 1.1。

添加库引用

另外,从Visual Studio中右击解决方案管理器中的引用节点并选择添加引用(或者直接从工具菜单中选择)

从左边选择更新。将会出现一系列的更新。点击更新。

clip_image007

一切都很好。现在我的AddMvc3ToWebForms NuGet 组件可以向ASP.NET WebForms项目里添加ASP.NET MVC功能,而并不需要额外的代码行。这带来了一个好的开箱即用的体验,尤其是如果我想要把它引入其他使用相同功能的项目里。