Codesmithツールを使用して、生成されたファイルを複数のプロジェクトに追加する方法
-
24-10-2019 - |
質問
私は現在のプロジェクトでCodesmithを使用しており、問題を理解しようとしています。 CodeSmithプロジェクト(.csp)では、現在のプロジェクト(.csproj)に生成されたすべてのファイルを自動的に追加するオプションを選択できます。しかし、私は複数のプロジェクト(.csproj)に出力を追加できるようにしたいと思っています。これを許可するコードスミスの内部にオプションはありますか?それとも、プログラム的にそれを行う良い方法はありますか?
ありがとう。
解決
Codesmithにこの問題を自動的に処理させる方法を理解できなかったため、ファイルの背後にあるコードにカスタムメソッドを書き、これを処理することになりました。
いくつかのメモ:-ProjファイルはXMLであるため、編集がかなり簡単ですが、プロジェクトに含まれるファイルのリストを保持する実際の「アイテムグループ」ノードは、実際には特別な方法でラベル付けされていません。最終的には、子ノードを「含む」「ItemGroup」ノードを選択することになりましたが、どの使用すべきかを判断するためのより良い方法があるかもしれません。 - 各ファイルが作成/更新されるのではなく、すべてのprojファイルの変更を一度に実行することをお勧めします。それ以外の場合は、Visual Studioから世代を立ち上げた場合、「このアイテムが変更された、リロードしたい」という洪水が得られるかもしれません - ファイルがソース制御下にある場合(そうですか?!)ファイルのチェックアウトを処理し、projファイルを編集してソースコントロールに追加する必要があります。
プロジェクトにファイルを追加するために使用したコードは(多かれ少なかれ)次のとおりです。
/// <summary>
/// Adds the given file to the indicated project
/// </summary>
/// <param name="project">The path of the proj file</param>
/// <param name="projectSubDir">The subdirectory of the project that the
/// file is located in, otherwise an empty string if it is at the project root</param>
/// <param name="file">The name of the file to be added to the project</param>
/// <param name="parent">The name of the parent to group the file to, an
/// empty string if there is no parent file</param>
public static void AddFileToProject(string project, string projectSubDir,
string file, string parent)
{
XDocument proj = XDocument.Load(project);
XNamespace ns = "http://schemas.microsoft.com/developer/msbuild/2003";
var itemGroup = proj.Descendants(ns + "ItemGroup").FirstOrDefault(x => x.Descendants(ns + "Compile").Count() > 0);
if (itemGroup == null)
throw new Exception(string.Format("Unable to find an ItemGroup to add the file {1} to the {0} project", project, file));
//If the file is already listed, don't bother adding it again
if(itemGroup.Descendants(ns + "Compile").Where(x=>x.Attribute("Include").Value.ToString() == file).Count() > 0)
return;
XElement item = new XElement(ns + "Compile",
new XAttribute("Include", Path.Combine(projectSubDir,file)));
//This is used to group files together, in this case the file that is
//regenerated is grouped as a dependent of the user-editable file that
//is not changed by the code generator
if (string.IsNullOrEmpty(parent) == false)
item.Add(new XElement(ns + "DependentUpon", parent));
itemGroup.Add(item);
proj.Save(project);
}
他のヒント
すべてのプロジェクトで参照できる共有アセンブリ(DLL)に編集することを考えましたか?
これはあなたの要件に合わないかもしれないことは知っていますが、これはすべてのプロジェクトが使用できる単一のソースを達成するための最良の方法の1つであり、必要に応じて維持するコードベースの1つだけであると思います。