SharePoint Online 向けに機能 (フィーチャー) をまとめる


※ SharePoint 2013 以降では、サンボボックス ソリューションは非推奨です。SharePoint アドイン (SharePoint Add-ins) による開発手法を使用してください。

環境 : Office 365 Beta (SharePoint 2010 Online), Visual Studio 2010

裏 10 行でズバリ ! サンドボックス ソリューション 

本シリーズは、「10 行でズバリ ! SharePoint 2010 開発」を理解された開発者向けに、さらに踏み込んだ内容を記載しています。(ちなみに、10 行にはおさまっていません。。。)

こんにちは。

今回は、SharePoint 2010 サンドボックス ソリューション (Sandboxed Solution) のまとめとして、機能の構成方法について、その考え方を説明します。

私のセッションでは、後半、実際の Office 365 (Beta 版) を使用して、下図のようなサンドボックス ソリューションのサンプルを紹介しました。

上記のデモでは、このブログでも説明してきた モジュールによるファイルの配置 (展開)外部ネットワークへの接続カスタムのリスト フォームXSL を使ったリスト ビュー などの手法を使用しています。そして、これら以外に、見えない作業として、ここで説明するような設定をおこなっています。

Site (サイト コレクション) か Web (サイト) か ?

まず、サンドボックスで作成するフィーチャー (Feature) のスコープ (Scope) について考えます。
Visual Studio 2010 で作成した各フィーチャーは、「サイトコレクション」(SPSite, Site)か「サイト」(SPWeb, Web) のいずれかのスコープを選択することができます。(下図参照)

では、サンドボックス ソリューションとして作成 (開発) するフィーチャーは、どちらのスコープで設定しておくべきでしょうか ?

まず、サンドボックス ソリューションの .wsp をアップロードする [ソリューション] ギャラリーは、必ずサイト コレクション単位で使用するという点をおぼえておいてください。つまり、サイト (SPWeb) のソリューション ギャラリーは存在しません。
このため、サンドボックス ソリューション (.wsp ファイル) のアップロードとアクティブ化は、必ず、サイト コレクション単位 (SPSite) でおこなわれます。

ソリューション ギャラリーにパッケージをアップロードしてアクティブ化すると、その機能 (フィーチャー) のスコープによって、アクティブ化 (Activate) の際に以下の通り機能が設定されます。

  • スコープ : サイト コレクション (SPSite) の機能の場合
    Web ソリューション パッケージ (.wsp) のアクティブ化 (Activate) と共に、そのサイト コレクション (厳密には、そのサイト コレクションのトップレベル サイト) の上で機能がアクティブ化され、すぐに機能が使用できる状態になります。
  • スコープ : サイト (SPWeb) の機能の場合
    Web ソリューション パッケージ (.wsp) のアクティブ化 (Activate) をおこなうと、そのサイト コレクション内の各サイトで、インストールされた機能 (フィーチャー) のアクティブ化ができるようになります。つまり、個々の機能 (フィーチャー) は自動的にアクティブ化されず、使用する際には、各サイトごとで機能 (フィーチャー) のアクティブ化 (Activate) をおこなう必要があります。

上記の通り記述すると、一見、サイト コレクション (SPSite) のスコープで作成しまうほうが手っ取り早いように思いますが、必ずしもそうではありません。
例えば、Office 365 (Beta) のサイト構成は、以下の通りになっています。

サイト コレクション (トップレベル サイト)       主にサイト コレクション単位の管理などで使用
サイト1       一般の利用者が使用
サイト2       一般の利用者が使用
. . .

つまり、実際にサイトを使用する場合には、サイト コレクションのルートにあるトップレベル サイトではなく、その下にサイトを作成して使用する場合があるため、機能 (フィーチャー) をサイト (SPWeb) のスコープで使用できるように構成しておく必要があります。(なお、本シリーズのこれまでの投稿では、動作確認とデバッグを簡素化する目的で、すべてサイト コレクション (SPSite) のスコープとして作成していますので注意してください。)

しかし、逆に、すべての機能をサイト (SPWeb) のスコープにすれば良いというわけではありません。
要素によっては、サイト コレクション (SPSite) のスコープでしか設定できないものがあります。例えば、Web パーツは、必ずサイト コレクション上の Web パーツ ギャラリー (/_catalogs/wp/Forms/) に登録する必要があります。この他に、カスタムのテーマや、Visual Studio で作成するコード ワークフローなどもサイト コレクション単位で設定する必要があります。(ただし、コード ワークフローはサンドボックス ソリューションとして作成できないため、ここでは無視してください。)

まとめると、機能 (フィーチャー) は、原則、サイト (SPWeb) のスコープで作成し、サイト コレクション (SPSite) 単位で設定すべきもの (Web パーツ、など) に限って、サイト コレクション (SPSite) のスコープで作成すると良いでしょう。

補足 : もちろん、例外もあります。例えば、プログラム コードを使ってサイト コレクションに対して設定をおこなうフィーチャー イベント レシーバーなどは、サイトごとに設定をおこなうと設定内容が重複するため、サイト コレクション単位で設定すると良いでしょう。

機能 (フィーチャー) をどのようにまとめるか

つぎに、機能 (フィーチャー) をどの単位でまとめ、どのように構成するかといったアイデアを記載します。

今、例えば、リスト定義とマスターページという 2 つの要素から構成されるパッケージ (.wsp) があると仮定します。利用する側の立場で考えると、当然、リスト定義の機能 (フィーチャー) と Web パーツの機能 (フィーチャー) を別々にアクティブ化 (Activate) したくはないでしょう。また、SharePoint が既定で持っている発行機能も、カスタム レイアウト、マスターページ設定など、複数の機能が 1 回のアクティブ化によって設定されます。
このように、必要な機能は、できるだけ 1 回のアクティブ化で済ませておくべきでしょう。

1 回のアクティブ化ですべての必要な設定をおこなうには、以下の 3 つの方法が考えられます。

方法1 : サイト テンプレートとして作成する

方法2 : 1 つの機能 (フィーチャー) にすべての要素を入れてしまう

方法3 : 機能 (フィーチャー) 間の依存関係を使用する (これについては後述します)

ここで、上記の 1、2 の方法は、実は、いくつかの問題点がありますので、以下に記載しておきます。

まず、方法 1 は、下図のように、サイトの新規作成時に選択可能な「テンプレート」としてソリューションを作成する方法です。

このテンプレートの中に、必要な機能 (フィーチャー) をすべて入れて、サイトの新規作成と同時にすべての機能をアクティブ化 (Activate) することで、多数の機能をテンプレートの中に 1 つにまとめることができます。

ここで注意すべき点は、サンドボックス ソリューションでは、「サイト定義」ではなく「サイト テンプレート」しか配置できないという点です。(サイト定義とサイト テンプレートの相違については 「10 行でズバリ !! SharePoint のサイト定義の作成」 を参照してください。)
つまり、Visual Studio で「サイト定義」を作成しても、サンドボックス ソリューションとしてインストールすることはできません。カスタムの「サイト テンプレート」を構築するには、SharePoint の画面から [テンプレートとしてサイトを保存] コマンドを選択して .wsp ファイルを作成し、このファイルを Visual Studio などで開いて編集することになります。
想像していただけるとわかりますが、これは、かなり退屈な作業です。(高度なスキルが必要です。)

つぎに、方法 2 は、マスターページ モジュール、リスト定義など、すべて (複数) の要素を 1 つのフィーチャーに入れてしまう方法です。下図 (下部) のように、Visual Studio 2010 のフィーチャー デザイナーを用いて、簡単に設定可能です。

注記 : ただし、サイト コレクション (SPSite) スコープの要素とサイト (SPWeb) スコープの要素を 1 つの機能 (フィーチャー) に混在できません。

この方法は、方法 1 と違って設定は簡単ですが、リスト定義とリスト インスタンスなど、関係性の深い複数の要素 (Element) をまとめる場合は有効ですが、この方法だけですべての要素を (1 つの機能に) まとめてしまうと、大規模な機能開発などの場合、モジュール性や柔軟性の観点で問題が生じます。
例えば、必要に応じて、A の機能 (フィーチャー) と B の機能 (フィーチャー) を利用者が選択して使用できると仮定します。そして、この双方の機能に同じ C の要素が含まれていると仮定しましょう。この場合、C を A と B の双方に重複して入れると、いろいろ問題が生じることになるでしょう。

つまり、方法 2 は、ソリューションが小さい場合は問題となりませんが、ソリューションが大きく、こうした機能間の柔軟性を考慮しなければならない場合には、現実的ではありません。

こうした背景から、以下では、上記の方法 3 の手順を紹介したいと思います。

依存関係を使用して機能 (Feature) をまとめる (手順の紹介)

ここでは、マスターページ (モジュール) 、Web パーツ、フィーチャー イベント レシーバー (SPFeatureReceiver) の各要素 (Element) を展開するソリューションを例に説明します。

まずは、以下の手順で、プロジェクトを準備します。

1) Visual Studio 2010 で [空の SharePoint プロジェクト] を新規作成します。(この際、[サンドボックス ソリューションとして配置する] を選択します。)

2) マスターページのモジュールを追加するため、Visual Studio で、ソリューション エクスプローラーのプロジェクトを右クリックして、[追加] – [新しい項目] で [モジュール] を選択します。以降は、「10 行でズバリ !! SharePoint のマスターページの作成」と同じ要領で、適宜、マスターページ (.master) を作成し、要素マニフェスト (Elements.xml) を変更します。(注意 : ただし、マップされたイメージファイルは使用しないでください。イメージ ファイルなどを配置する場合は、「SharePoint 2010 モジュールを使ったファイルのサンドボックス配置」で説明した通り、モジュールを使用してください。)

3) 前述の通り、Visual Studio を使って、この機能 (Feature1) のスコープが「Web」になっていることを確認します。

4) つぎに、Visual Studio で、ソリューション エクスプローラーのプロジェクトを右クリックして、[追加] – [新しい項目] で [Web パーツ] を選択します。以降は、「10 行でズバリ!! SharePoint のサンドボックス ソリューションの作成」と同じ要領で、適宜、Web パーツのコードを記述します。

5) 前述の通り、Web パーツはサイト コレクション (SPSite) の機能であるため、この機能 (Feature2) のスコープは「Site」のままにしておいてください。

6) つぎに、フィーチャー イベント レシーバー (SPFeatureReceiver) を追加するため、Visual Studio のソリューション エクスプローラーで [Features] フォルダを右クリックして、[フィーチャーの追加] メニューを選択します。作成されたフィーチャー フォルダーを右クリックして [イベント レシーバーの追加] を選択して、コードを実装します。今回は、フィーチャーのインストールと同時に、上記のマスターページ (SampleMasterPage.master と仮定します) を設定するため、以下のコードを実装しておきましょう。

. . .

using Microsoft.SharePoint.Utilities;
. . .

public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
    // サイト (SPWeb) またはサイトコレクション (SPSite) の SPWeb を取得します
    SPWeb web;
    if (properties.Feature.Parent is SPWeb)
        web = (SPWeb)properties.Feature.Parent; //サイトの場合
    else
        web = ((SPSite)properties.Feature.Parent).RootWeb; //サイトコレクションの場合

    web.AllowUnsafeUpdates = true;

    // [ページ] 内のすべてのページにマスターページを適用
    web.CustomMasterUrl = SPUrlUtility.CombineUrl(web.ServerRelativeUrl,
        "_catalogs/masterpage/SampleMasterPageModule/SampleMasterPage.master");
    // システムのページ (設定画面など) にマスターページを適用
    web.MasterUrl = SPUrlUtility.CombineUrl(web.ServerRelativeUrl,
        "_catalogs/masterpage/SampleMasterPageModule/SampleMasterPage.master");
    web.Update();
}
. . .

public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
{
    // サイト (SPWeb) またはサイトコレクション (SPSite) の SPWeb を取得します
    SPWeb web;
    if (properties.Feature.Parent is SPWeb)
        web = (SPWeb)properties.Feature.Parent; //サイトの場合
    else
        web = ((SPSite)properties.Feature.Parent).RootWeb; //サイトコレクションの場合

    web.AllowUnsafeUpdates = true;

    // [ページ] 内のすべてのページにマスターページを適用
    web.CustomMasterUrl = SPUrlUtility.CombineUrl(web.ServerRelativeUrl,
        "_catalogs/masterpage/v4.master");
    // システムのページ (設定画面など) にマスターページを適用
    web.MasterUrl = SPUrlUtility.CombineUrl(web.ServerRelativeUrl,
        "_catalogs/masterpage/v4.master");
    web.Update();
}

7) Visual Studio を使って、この追加した機能 (Feature3) のスコープが「Web」になっていることを確認します。

これらの機能 (Feature1, Feature2, Feature3) が含まれたソリューション (.wsp) を、利用者が、どのようにインストールして、どのように使用すべきか想像してみてください。

まず、Web パーツ (Feature2) は、前述の通り、サイト コレクション (Site) スコープの機能であるため、サイト コレクション (トップレベル サイト) でソリューションをアップロードしてアクティブ化 (Activate) をおこなうと同時に、この Web パーツが「使用可能な状態」になり、その他の機能 (マスターページとイベント レシーバーを含んだ機能) は、使用する各サイト上で「アクティブ化 (Activate) 可能な状態」になります。
しかし、この設定のままだと、利用者は、機能を使用する際に、サイト上で、マスターページの機能 (Feature1) とイベント レシーバーの機能 (Feature3) の 2 つをアクティブ化する必要があります。
そこで、前述した方法 3 (依存関係を使う方法) で、1 回の機能のインストールで、必要となるすべての機能のアクティブ化をおこなうように設定します。

まず、内部のメカニズムについて説明しておきましょう。

SharePoint では、機能 (フィーチャー) のフィーチャー マニフェスト (feature.xml) に以下の通り設定することで、このフィーチャーをインストールすると同時に、依存する他のフィーチャーを同時にインストールすることができます。

<?xml version="1.0" encoding="utf-8" ?>
<Feature  . . .>
    <ActivationDependencies>
      <ActivationDependency FeatureId="アクティブ化するフィーチャー Id" />
      <ActivationDependency FeatureId="アクティブ化するフィーチャー Id" />
      . . .
    </ActivationDependencies>
</Feature>

つまり、この手法を使用して、1 回のアクティブ化で、複数の機能 (Feature) をインストールさせるのですが、Visual Studio 2010 では、以下の手順で、この設定を UI を使って簡単に設定できます。

まず、利用者にとってエントリー ポイントとなるフィーチャーを作成するため、Visual Studio のソリューション エクスプローラーで [Features] フォルダを右クリックして [フィーチャーの追加] メニューを選択します。(Feature4 が新規作成されます。)
Visual Studio のソリューションエクスプローラーで、上記で作成された Feature4 を右クリックして、[デザイナーの表示] メニューを選択してフィーチャー デザイナーを表示すると、画面下部に、[フィーチャー アクティブ化依存関係] 欄があるため、ここで [追加] ボタンを押して、上記のマスターページのフィーチャー (Feature1) とイベント レシーバーのフィーチャー (Feature3) を追加します。

注意 : ここでは説明を省略しますが、アクティブ化をおこなう順番にも注意してください。

さいごに、Feature1 (マスターページのフィーチャー)、Feature3 (イベント レシーバーのフィーチャー) を利用者から隠しておくため、Feature1、Feature3 のフィーチャー デザイナーを表示して、プロパティ画面で、[非表示] 属性 (Hidden 属性) を True に設定します。(下図)

動作確認

では、動作を確認してみましょう。

  1. 上記で作成したプロジェクトのパッケージ (.wsp) を作成します。(Visual Studio のソリューション エクスプローラーで、プロジェクトを右クリックして、[パッケージ] を選択します。)
  2. トップレベル サイトの [ソリューション] ギャラリーを表示します。(Office 365 では、サイトの設定画面を表示して、[トップレベルのサイト設定に移動] をクリックします。表示される画面で、[ソリューション] を選択します。)
  3. 上記の .wsp ファイルをソリューション ギャラリーにアップロードし、アクティブ化 (Activate) をおこないます。(この段階では、上記の Feature1、Feature3、Feature4 はアクティブ化されません。)
  4. サイト (サブサイト、またはトップレベル サイト) に戻り、[サイト機能の管理] をクリックします。
    すると、下図の通り、Feature4 以外はユーザーから見えないようになっています。
  5. 上図のフィーチャー (Feature4) のアクティブ化をおこなうと、下図の通り、サイトのマスターページが自動で設定されます。(内部では、マスターページのモジュールなどが、ちゃんとアクティブ化されています。)

注意 : なお、リスト インスタンスや、ギャラリーに登録されたマスターページ、Web パーツなどのモジュール (Module) は、フィーチャーの非アクティブ化 (Deactivate) によって消去されません。(これは、SharePoint の仕様です。例えば、リスト インスタンスにデータが登録されている場合などもあるため、安全のため、削除はおこないません。)
このため、必要に応じ、イベント レシーバーなどを使用して消すようにしてください。(あるいは、手動で削除をおこなってください。)

まとめ

例えば、先日お見せしたデモ (Microsoft Conference 2010) では、リスト フォームをカスタマイズするために、カスタムのサンドボックス Web パーツを使用していますが、この Web パーツをリスト フォーム以外の場所で勝手に使用できないよう、ここで紹介した手法 (上記) を使って、Web パーツを非表示 (Hidden) にしています。
さらに、Visual Studio では、ある要素 (Element) A をサイト コレクション (Site) スコープの機能として設定し、サイト (Web) スコープの別の要素 B を作成した場合、これら 2 つの要素 A, B は異なる機能 (Feature) として設定されます。(あとから、要素 A を Web スコープに変更しても、これらは同一の機能には含まれません。) つまり、構築する手順や作成方法によって、要素 (Element) と機能 (Feature) の関係が異なってきます。

こうしたさまざまな理由から、ここで紹介した要素と機能の設定 (または、確認) は、必ず、開発の段階で必要となるので、是非、概念や考え方をおぼえておいてください。

このシリーズでは、SharePoint に着目してサンドボックス ソリューションの紹介をしましたが、次期 Dynamics CRM Online (または Dynamics CRM 2011) においても、サーバー上のイン プレースのソリューション (サンドボックス ソリューション) の構築が可能です。(さらに、SharePoint 同様、LINQ、REST、Client OM なども使用できます。)

サンドボックス ソリューションでは安全性に配慮したさまざまな制約はありますが、概念を理解してしまえば、従来の SaaS ではむずかしかった非常に柔軟なアプリケーション拡張が可能になりますので、開発者の方は、是非、習得しておきましょう。

 

Comments (0)

Skip to main content