Share via


如何:使用升级代码激活具有依赖项的功能

上次修改时间: 2010年9月21日

适用范围: SharePoint Foundation 2010

功能升级基础结构可自动检测并升级其他功能所依赖的功能,因此,如果向 Feature.xml 文件中添加 <ActivationDependencies> 部分,则无需添加任何特定升级代码即可支持升级被依赖的功能。但是,如果激活依赖关系是尚未激活的可见功能,则必须编写功能升级代码来确保在功能升级期间激活其他功能所依赖的可见功能。此高级方案必须通过一个进程来实现自定义升级代码,以激活其他功能所依赖的可见功能。下面的高级功能升级方案中介绍了此进程的一个示例。

使用自定义升级代码激活具有功能依赖关系的功能

  1. Feature.xml 文件中添加一个 <ActivationDependency> 标记。现在,<ActivationDependency> 元素具有一个 MinimumVersion 属性,可为进行版本管理的功能依赖关系提供支持。在对象模型中,SPFeatureDependency 类具有一个对应的 MinimumVersion 属性,该属性返回在 Feature.xml 文件中指定的值。当您要确保已安装和激活"被依赖"功能的所需版本时,进行版本管理的功能依赖关系将非常有用。

  2. 增大功能版本号。有关详细信息,请参阅使用功能版本的最佳实践

  3. Feature.xml 文件中添加 <UpgradeActions> 部分,并引用功能接收器的程序集和类型。本部分指定要执行操作的名称。在此示例中,将操作"ActivateFeature"传递给您稍后将在步骤 4 中定义的 FeatureUpgrading(SPFeatureReceiverProperties, String, IDictionary<String, String>) 方法的实现。

    <?xml version="1.0" encoding="utf-8"?>
    <Feature 
      Id = "712224F9-6708-4965-A18C-B73CA86AEFCA"
      ReceiverAssembly = "MyFeatureReceiver, Version = 1.0.0.0, Culture = neutral, PublicKeyToken = 3ef91b1292056a22"
      ReceiverClass = "MyFeatureReceiver.MyReceiver"
      Title="My Feature" 
      Description="My feature" 
      Version="2.0.0.0"
      ImageUrl="MyFeature.gif"
      Scope="Site" 
      Hidden="FALSE"
      DefaultResourceFile="core"
      xmlns="https://schemas.microsoft.com/sharepoint/">
      <ElementManifests>
        <ElementManifest Location="Elements.xml" />
        <ElementManifest Location="Elements2.xml" />
      </ElementManifests>
      <ActivationDependencies>
        <ActivationDependency FeatureId="3A4CE811-6FE0-4e97-A6AE-675470282CF2" />
      </ActivationDependencies>
      <UpgradeActions
        ReceiverAssembly="MyFeatureReceiver, Version=1.0.0.0, Culture=neutral, PublicKeyToken=3ef91b1292056a22" 
        ReceiverClass="MyFeatureReceiver.MyReceiver">
        <VersionRange EndVersion="2.0.0.0">
          <CustomUpgradeAction Name="ActivateFeature"/>
          <ApplyElementManifests>
            <ElementManifest Location="Elements2.xml"/>
          </ApplyElementManifests>
        </VersionRange>
      </UpgradeActions>
    </Feature>
    
  4. 实现派生自 SPFeatureReceiver 且替代 FeatureUpgrading(SPFeatureReceiverProperties, String, IDictionary<String, String>) 方法的功能接收器。如以下示例所示,可将您在步骤 3 中指定的功能标识符传递给 Add() 方法,以便在升级期间激活同一范围内可见的"被依赖"功能。

    public override void FeatureUpgrading(SPFeatureReceiverProperties properties, string upgradeActionName, IDictionary<string, string> parameters)
    {
        if(upgradeActionName != "ActivateFeature")
        return;
        // Get the current Feature that is being upgraded.
        SPFeature thisFeature = properties.Feature;
     
        // Get the parent of the current Feature.
        object featureParent = thisFeature.Parent;
     
        // Get the appropriate Feature collection, based on scope.
        SPFeatureCollection featureCollection = null;
        switch (thisFeature.Definition.Scope)
        {
            case SPFeatureScope.Farm:
                
                featureCollection = ((SPWebService) featureParent).Features;
                break;
     
            case SPFeatureScope.WebApplication:
     
                featureCollection = ((SPWebApplication) featureParent).Features;
                break;
     
            case SPFeatureScope.Site:
     
                featureCollection = ((SPSite) featureParent).Features;
                break;
     
            case SPFeatureScope.Web:
     
                featureCollection = ((SPWeb) featureParent).Features;
                break;
        }
     
        // Get the Feature dependencies.
        SPFeatureDependencyCollection featureDepdencyCollection = thisFeature.Definition.ActivationDependencies;
     
        /* Loop over each dependency and activate it if it has same scope and was not already activated.*/
        foreach (SPFeatureDependency featureDependency in featureDepdencyCollection)
        {
            // Get the depended-upon Feature definition.
            SPFeatureDefinition dependedUponFeatureDefinition = null;
            try
            {
                dependedUponFeatureDefinition = SPFarm.Local.FeatureDefinitions[featureDependency.FeatureId];
            }
            catch { }
     
            // Get the depended-upon Feature.
            SPFeature dependedUponFeature = null;
            try
            {
                dependedUponFeature = featureCollection[featureDependency.FeatureId];
            }
            catch { }
     
            // Get the depended-upon Feature scope.
            if (dependedUponFeatureDefinition != null && dependedUponFeature == null)
            {
                if (dependedUponFeatureDefinition.Scope == thisFeature.Definition.Scope)
                {
                    featureCollection.Add(dependedUponFeatureDefinition.Id);
                }
            }
        }
    }