Поделиться через


Практическое руководство. Использование кода обновления для активации компонента с зависимостями

Дата последнего изменения: 21 сентября 2010 г.

Применимо к: SharePoint Foundation 2010

Инфраструктура обновления компонентов автоматически обнаруживает и обновляет компоненты, от которых зависят другие компоненты, поэтому при добавлении раздела <ActivationDependencies> в файл Feature.xml не требуется добавлять никакого специального кода обновления для поддержки зависимых компонентов. Однако если зависимый компонент активируемого компонента еще не был активирован и является видимым, необходимо создать код обновления компонента, чтобы гарантировать активацию этого видимого компонента вместе с другими зависимыми от него компонентами во время обновления. Этот расширенный сценарий влечет за собой процесс реализации пользовательского кода обновления для активации видимого компонента, от которого зависят другие компоненты. Пример такого процесса приведен в следующем расширенном сценарии обновления компонента.

Использование пользовательского кода обновления для активации компонента, имеющего зависимые компоненты

  1. Добавьте тег <ActivationDependency> в файл Feature.xml. Теперь у элемента <ActivationDependency> есть атрибут MinimumVersion, обеспечивающий поддержку зависимостей версий компонентов. В объектной модели у класса SPFeatureDependency есть соответствующее свойство MinimumVersion, возвращающее значение, заданное в файле Feature.xml. Зависимости версий компонентов полезны, если нужно гарантировать установку и активацию необходимой версии компонента, от которой зависят другие компоненты.

  2. Увеличьте номер версии компонента. Дополнительные сведения см. в разделе Рекомендации по использованию версий компонентов.

  3. Добавьте раздел <UpgradeActions> в файл Feature.xml и вставьте ссылку на сборку и тип приемника компонента. В этом разделе определяется имя выполняемого действия. В этом примере действие "ActivateFeature" передается реализации метода FeatureUpgrading(SPFeatureReceiverProperties, String, IDictionary<String, String>), определяемой позже, в шаге 4.

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