5951
Sandcastle Help File Builderを使用してC#ソリューションのヘルプを作成しています。

ヘルプに出力されるメンバーをアセンブリ(名前空間も分離しています)とアクセス修飾子に応じて変更したいのですが、GUIによるAPI
Filterの指定はメンバー毎となっているため指定に非常に手間がかかります。リフレクションを使用してshfbprojファイルに除外メンバーを書き込む手もありますが、パターンマッチングやアドオンなどを使用してスマートに解決する方法はないでしょうか。
CC BY-SA 3.0
2015-01-23T11:21:17.163
5154
2015-02-04T14:28:02.297
5750
question
c# sandcastle
SandcastleのAPI Filterを包括的に指定したい
プラグインによる`ApiFilter`のビルド時カスタマイズ方法を調べました。

  1. プラグインを定義するプロジェクトで`Sandcastle Help File Builder`インストールフォルダ内のの`SandcastleBuilder.Utils.dll`を参照する。
  2. `SandcastleBuilder.Utils.BuildComponent.IPlugIn`の実装クラスを作成し、`HelpFileBuilderPlugInExportAttribute`を指定する。
  3. `IPlugIn.ExecutionPoints`で`new ExecutionPoint(BuildStep.GenerateApiFilter, ExecutionBehaviors.After)`を返す。
  4. `IPlugIn.Initialize`で`BuildProcess`を確保し、`IPlugIn.Execute`で`BuildProcess.BuildApiFilter`に対して`MergeEntry`等で変更を加える。
  5. 作成したアセンブリをSandcastleプロジェクトのルートディレクトリまたは`Project-specific components path`で指定したフォルダに配置する。
  6. `Plug-Ins`で作成したプラグインを選択する。

なおMRefBuilder.configの`ApiFilter`はshfbprojと同様に`Namespace`、`Type`、`Member`の3層構造を取るのでエントリーの作成も階層化する必要があります。

```

    [HelpFileBuilderPlugInExport("TestPlugIn")]
    public class TestPlugIn : IPlugIn
    {
        private BuildProcess _BuildProcess;
        private List<ExecutionPoint> _ExecutionPoints;
    
        public string ConfigurePlugIn(SandcastleBuilder.Utils.SandcastleProject project, string currentConfig)
        {
            return currentConfig;
        }
    
        public void Initialize(BuildProcess buildProcess, System.Xml.XPath.XPathNavigator configuration)
        {
            _BuildProcess = buildProcess;
        }
    
        public IEnumerable<ExecutionPoint> ExecutionPoints
        {
            get
            {
                if (_ExecutionPoints == null)
                {
                    _ExecutionPoints = new List<ExecutionPoint>() 
                    {
                        new ExecutionPoint(BuildStep.GenerateApiFilter, ExecutionBehaviors.After)
                    };
                }
                return _ExecutionPoints;
            }
        }
    
        public void Execute(ExecutionContext context)
        {
            _BuildProcess.BuildApiFilter.MergeEntry(SandcastleBuilder.Utils.ApiEntryType.Namespace, "SandcastleTest.Sources.ShouldBeExcluded", false, true);
    
            if (_BuildProcess.BuildApiFilter.MergeEntry(SandcastleBuilder.Utils.ApiEntryType.Namespace, "SandcastleTest.Sources.MayBeExcluded", true, true))
            {
                var ns = _BuildProcess.BuildApiFilter.Last();
    
                ns.Children.MergeEntry(SandcastleBuilder.Utils.ApiEntryType.Class, "Class3", false, true);
    
                if (ns.Children.MergeEntry(SandcastleBuilder.Utils.ApiEntryType.Class, "Class4", true, true))
                {
                    ns.Children.Last().Children.MergeEntry(SandcastleBuilder.Utils.ApiEntryType.Method, "Method", false, true);
                }
            }
        }
    
        public void Dispose()
        {
            _BuildProcess = null;
            _ExecutionPoints = null;
        }
    }
    
```
CC BY-SA 3.0
2015-02-04T14:28:02.297
5951
2015-02-04T14:28:02.297
5750
5154
answer