アップグレード コードを使用して依存関係を持つ機能を有効にする

最終更新日: 2010年9月21日

適用対象: SharePoint Foundation 2010

機能アップグレード インフラストラクチャでは、他の機能から依存されている機能が自動的に検出されアップグレードされます。したがって、<ActivationDependencies> セクションを Feature.xml ファイルに追加すれば、特定のアップグレード コードを追加して、依存されている機能のアップグレードをサポートする必要はありません。ただし、アクティブ化の依存関係が、まだアクティブ化されていない表示可能機能の場合は、機能アップグレード コードを記述して、他の機能から依存されている表示可能機能が機能アップグレード中にアクティブ化されたことを確認する必要があります。この高度なシナリオでは、他の機能から依存されている表示可能機能をアクティブ化するために、カスタム アップグレード コードを実装するプロセスが必要です。次の高度な機能アップグレード シナリオでは、このプロセスの一例について説明します。

カスタム アップグレード コードを使用して、機能の依存関係を持つ機能をアクティブ化する

  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);
                }
            }
        }
    }