Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/dotnet-svcutil/lib/src/CommandProcessorOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ internal class CommandSwitches
public readonly CommandSwitch AcceptCertificate = new CommandSwitch(AccecptCertificateKey, "ac", SwitchType.Flag);
public readonly CommandSwitch ServiceContract = new CommandSwitch(ServiceContractKey, "sc", SwitchType.Flag);
public readonly CommandSwitch Language = new CommandSwitch(LanguageKey, "l", SwitchType.SingletonValue, OperationalContext.Global);
public readonly CommandSwitch SeparateFiles = new CommandSwitch(SeparateFilesKey, "sf", SwitchType.Flag);

public void Init() { } // provided as a way to get the static class Switches loaded early.
}
Expand Down
3 changes: 2 additions & 1 deletion src/dotnet-svcutil/lib/src/HelpGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,8 @@ private static void WriteCodeGenerationHelp()
ArgumentInfo.CreateParameterHelpInfo(CommandProcessorOptions.Switches.TargetFramework.Name, SR.ParametersTargetFramework, string.Format(SR.HelpTargetFrameworkFormat, CommandProcessorOptions.Switches.TargetFramework.Abbreviation)),
ArgumentInfo.CreateFlagHelpInfo( CommandProcessorOptions.Switches.AcceptCertificate.Name, string.Format(SR.HelpAcceptCertificateFormat, CommandProcessorOptions.Switches.AcceptCertificate.Abbreviation)),
ArgumentInfo.CreateFlagHelpInfo( CommandProcessorOptions.Switches.ServiceContract.Name, string.Format(SR.HelpServiceContractFormat, CommandProcessorOptions.Switches.ServiceContract.Abbreviation)),
ArgumentInfo.CreateFlagHelpInfo( CommandProcessorOptions.Switches.Language.Name, string.Format(SR.HelpLanguage, CommandProcessorOptions.Switches.Language.Abbreviation))
ArgumentInfo.CreateFlagHelpInfo( CommandProcessorOptions.Switches.Language.Name, string.Format(SR.HelpLanguage, CommandProcessorOptions.Switches.Language.Abbreviation)),
ArgumentInfo.CreateFlagHelpInfo( CommandProcessorOptions.Switches.SeparateFiles.Name, string.Format(SR.HelpSeparateFiles, CommandProcessorOptions.Switches.SeparateFiles.Abbreviation))
}
};

Expand Down
3 changes: 3 additions & 0 deletions src/dotnet-svcutil/lib/src/SR.resx
Original file line number Diff line number Diff line change
Expand Up @@ -637,4 +637,7 @@ Your credentials will be sent to the server in clear text.</value>
<data name="HelpLanguage" xml:space="preserve">
<value>The programming language to use for generating code. Examples of language names to use are CS and VB. Default: C#. (Short Form: -{0})</value>
</data>
<data name="HelpSeparateFiles" xml:space="preserve">
<value>Creates separate files for each type in the specified output directory. (Short Form: -{0})</value>
</data>
</root>
5 changes: 4 additions & 1 deletion src/dotnet-svcutil/lib/src/Shared/Options/UpdateOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ internal partial class UpdateOptions : ApplicationOptions
public const string TypeReuseModeKey = "typeReuseMode";
public const string WrappedKey = "wrapped";
public const string LanguageKey = "language";
public const string SeparateFilesKey = "separateFiles";
#endregion

#region properties
Expand All @@ -49,6 +50,7 @@ internal partial class UpdateOptions : ApplicationOptions
public TypeReuseMode? TypeReuseMode { get { return GetValue<TypeReuseMode?>(TypeReuseModeKey); } set { SetValue(TypeReuseModeKey, value); } }
public bool? Wrapped { get { return GetValue<bool?>(WrappedKey); } set { SetValue(WrappedKey, value); } }
public string Language { get { return GetValue<string>(LanguageKey); } set { SetValue(LanguageKey, value); } }
public bool? SeparateFiles { get { return GetValue<bool?>(SeparateFilesKey); } set { SetValue(SeparateFilesKey, value); } }
#endregion

public UpdateOptions()
Expand All @@ -70,7 +72,8 @@ public UpdateOptions()
new SingleValueOption<FrameworkInfo>(TargetFrameworkKey),
new SingleValueOption<TypeReuseMode>(TypeReuseModeKey),
new SingleValueOption<bool>(WrappedKey),
new SingleValueOption<string>(LanguageKey));
new SingleValueOption<string>(LanguageKey),
new SingleValueOption<bool>(SeparateFilesKey) { SerializationName = "separateFiles" });
}

public static UpdateOptions FromFile(string filePath, bool throwOnError = true)
Expand Down
32 changes: 26 additions & 6 deletions src/dotnet-svcutil/lib/src/Tool.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using Microsoft.Tools.ServiceModel.Svcutil.Metadata;
using System;
using System.Collections.Generic;
using System.Diagnostics;
Expand All @@ -13,6 +12,8 @@
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeDom;
using Microsoft.Tools.ServiceModel.Svcutil.Metadata;
using DcNS = System.Runtime.Serialization;

namespace Microsoft.Tools.ServiceModel.Svcutil
Expand Down Expand Up @@ -244,12 +245,31 @@ await serviceDescriptor.ImportMetadataAsync(
using (await SafeLogger.WriteStartOperationAsync(options.Logger, "Processing Code DOM ...").ConfigureAwait(false))
{
ToolConsole.WriteLine(SR.GeneratingFiles);
if (options.SeparateFiles == true)
{
foreach (CodeNamespace @namespace in importModule.CodeCompileUnit.Namespaces)
{
foreach (CodeTypeDeclaration type in @namespace.Types)
{
options.OutputFile = new FileInfo(Path.Combine(options.OutputDir.FullName, $"{type.Name}{CodeSerializer.GetOutputFileExtension(options)}"));
Comment thread
mr-sven marked this conversation as resolved.
Outdated
CodeSerializer codeSerializer = new CodeSerializer(options, serviceDescriptor.MetadataDocuments);
CodeCompileUnit compileUnit = new CodeCompileUnit();
CodeNamespace splitNamespace = new CodeNamespace(@namespace.Name);
compileUnit.Namespaces.Add(splitNamespace);
splitNamespace.Types.Add(type);
var filePath = codeSerializer.Save(compileUnit);
Comment thread
mr-sven marked this conversation as resolved.
Outdated
ToolConsole.WriteLine(filePath, LogTag.Important);
Comment thread
mr-sven marked this conversation as resolved.
Outdated
}
}
Comment thread
mr-sven marked this conversation as resolved.
Outdated
}
Comment on lines +251 to +296

Copilot AI Apr 10, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When SeparateFiles is enabled, the tool writes many .cs files but does not appear to clean up previously generated type files in the output directory. This can leave stale types behind on reruns/updates and cause compilation conflicts. Consider deleting previously generated type files (or generating into a dedicated subfolder and managing it) before writing the new set.

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mconnew I'm not sure about this, cleaning up the output directory is nothing I would recommend. That should be a user task.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry it's taken a while to get back to this. Basically the problem is you run the tool against a wsdl once, and it generates TypeA.cs and TypeB.cs. The wsdl is then modified and TypeA is no longer a part of the contract. You then update the generated code with the latest wsdl changes. You now have TypeA.cs lingering in your build which is unused. When this was a single file output, TypeA would cease to exist in the generated code after an update. The user isn't expected to touch any of the source files generated by dotnet-svcutil. It's generated into a separate folder and is meant to be tool managed. It's not treated like a template code generate where it creates the file and now it's yours to own.

Comment on lines +251 to +296

Copilot AI Apr 10, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New separate-files behavior is introduced here, but there’s no accompanying test coverage verifying (1) multiple files are produced, (2) names are deterministic/collision-safe, and (3) update/rerun behavior doesn’t leave stale files. Since this repo has an existing baseline/E2E test harness, it would be good to add a targeted test case for --separateFiles/-sf.

Copilot uses AI. Check for mistakes.
else
{
CodeSerializer codeSerializer = new CodeSerializer(options, serviceDescriptor.MetadataDocuments);
var filePath = codeSerializer.Save(importModule.CodeCompileUnit);

CodeSerializer codeSerializer = new CodeSerializer(options, serviceDescriptor.MetadataDocuments);
var filePath = codeSerializer.Save(importModule.CodeCompileUnit);

// When in Infrastructure mode (WCF CS) it is assumed the output file path have been provided so no need to display it.
ToolConsole.WriteLineIf(options.ToolContext != OperationalContext.Infrastructure, filePath, LogTag.Important);
// When in Infrastructure mode (WCF CS) it is assumed the output file path have been provided so no need to display it.
ToolConsole.WriteLineIf(options.ToolContext != OperationalContext.Infrastructure, filePath, LogTag.Important);
}
}

return ToolConsole.ExitCode;
Expand Down
7 changes: 6 additions & 1 deletion src/dotnet-svcutil/lib/src/xlf/SR.cs.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -617,6 +617,11 @@ Identifikátor dokumentu: {0}</target>
<target state="translated">Vygenerovat kód pro kontrakty služeb Třída klienta se nevygeneruje. (Krátký tvar: -{0})</target>
<note />
</trans-unit>
<trans-unit id="HelpSeparateFiles">
<source>Creates separate files for each type in the specified output directory. (Short Form: -{0})</source>
<target state="new">Creates separate files for each type in the specified output directory. (Short Form: -{0})</target>
Comment thread
mr-sven marked this conversation as resolved.
<note />
</trans-unit>
<trans-unit id="HelpSyncFormat">
<source>Generate synchronous methods for operations in addition to async. (Short Form: -{0})</source>
<target state="translated">Kromě asynchronních metod generovat pro operace i synchronní metody (krátký tvar: -{0})</target>
Expand Down Expand Up @@ -873,4 +878,4 @@ Vaše přihlašovací údaje se odešlou na server v podobě prostého textu.</t
</trans-unit>
</body>
</file>
</xliff>
</xliff>
7 changes: 6 additions & 1 deletion src/dotnet-svcutil/lib/src/xlf/SR.de.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -617,6 +617,11 @@ Dokumentbezeichner: "{0}".</target>
<target state="translated">Generieren Sie Code für Dienstleistungsverträge. Die Clientklasse wird nicht generiert. (Kurzform: -{0})</target>
<note />
</trans-unit>
<trans-unit id="HelpSeparateFiles">
<source>Creates separate files for each type in the specified output directory. (Short Form: -{0})</source>
<target state="new">Creates separate files for each type in the specified output directory. (Short Form: -{0})</target>
Comment thread
mr-sven marked this conversation as resolved.
<note />
</trans-unit>
<trans-unit id="HelpSyncFormat">
<source>Generate synchronous methods for operations in addition to async. (Short Form: -{0})</source>
<target state="translated">Hiermit werden synchrone Methoden für Vorgänge generiert, die zusätzlich zu asynchronen Vorgängen ausgeführt werden. (Kurzform: -{0})</target>
Expand Down Expand Up @@ -873,4 +878,4 @@ Die Anmeldeinformationen werden in Klartext an den Server gesendet.</target>
</trans-unit>
</body>
</file>
</xliff>
</xliff>
7 changes: 6 additions & 1 deletion src/dotnet-svcutil/lib/src/xlf/SR.es.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -617,6 +617,11 @@ Identificador del documento: "{0}".</target>
<target state="translated">Generar código para Service Contracts. La clase cliente no se generará. (Forma corta: {0})</target>
<note />
</trans-unit>
<trans-unit id="HelpSeparateFiles">
<source>Creates separate files for each type in the specified output directory. (Short Form: -{0})</source>
<target state="new">Creates separate files for each type in the specified output directory. (Short Form: -{0})</target>
Comment thread
mr-sven marked this conversation as resolved.
<note />
</trans-unit>
<trans-unit id="HelpSyncFormat">
<source>Generate synchronous methods for operations in addition to async. (Short Form: -{0})</source>
<target state="translated">Genere métodos sincrónicos para las operaciones además de los asincrónicos. (Forma corta: -{0})</target>
Expand Down Expand Up @@ -873,4 +878,4 @@ Las credenciales se enviarán al servidor en texto no cifrado.</target>
</trans-unit>
</body>
</file>
</xliff>
</xliff>
7 changes: 6 additions & 1 deletion src/dotnet-svcutil/lib/src/xlf/SR.fr.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -617,6 +617,11 @@ Identificateur de document : '{0}'.</target>
<target state="translated">Générez du code pour les contrats de service. La classe cliente ne sera pas générée. (Forme abrégée : -{0})</target>
<note />
</trans-unit>
<trans-unit id="HelpSeparateFiles">
<source>Creates separate files for each type in the specified output directory. (Short Form: -{0})</source>
<target state="new">Creates separate files for each type in the specified output directory. (Short Form: -{0})</target>
Comment thread
mr-sven marked this conversation as resolved.
<note />
</trans-unit>
<trans-unit id="HelpSyncFormat">
<source>Generate synchronous methods for operations in addition to async. (Short Form: -{0})</source>
<target state="translated">Générez des méthodes synchrones pour les opérations en plus des méthodes asynchrones. (Forme abrégée : -{0})</target>
Expand Down Expand Up @@ -873,4 +878,4 @@ Vos informations d'identification vont être envoyées au serveur en texte clair
</trans-unit>
</body>
</file>
</xliff>
</xliff>
7 changes: 6 additions & 1 deletion src/dotnet-svcutil/lib/src/xlf/SR.it.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -617,6 +617,11 @@ Identificatore di documento: '{0}'.</target>
<target state="translated">Generare il codice per i contratti di servizio. La classe client non verrà generata. (Forma breve: -{0})</target>
<note />
</trans-unit>
<trans-unit id="HelpSeparateFiles">
<source>Creates separate files for each type in the specified output directory. (Short Form: -{0})</source>
<target state="new">Creates separate files for each type in the specified output directory. (Short Form: -{0})</target>
Comment thread
mr-sven marked this conversation as resolved.
<note />
</trans-unit>
<trans-unit id="HelpSyncFormat">
<source>Generate synchronous methods for operations in addition to async. (Short Form: -{0})</source>
<target state="translated">Genera metodi sincroni per le operazioni oltre a quelli asincroni. Forma breve: -{0}</target>
Expand Down Expand Up @@ -873,4 +878,4 @@ Le credenziali verranno inviate al server come testo non crittografato.</target>
</trans-unit>
</body>
</file>
</xliff>
</xliff>
7 changes: 6 additions & 1 deletion src/dotnet-svcutil/lib/src/xlf/SR.ja.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -617,6 +617,11 @@ Document Identifier: '{0}'.</source>
<target state="translated">サービス コントラクトのコードを生成します。クライアント クラスは生成されません。(短い形式: -{0})</target>
<note />
</trans-unit>
<trans-unit id="HelpSeparateFiles">
<source>Creates separate files for each type in the specified output directory. (Short Form: -{0})</source>
<target state="new">Creates separate files for each type in the specified output directory. (Short Form: -{0})</target>
Comment thread
mr-sven marked this conversation as resolved.
<note />
</trans-unit>
<trans-unit id="HelpSyncFormat">
<source>Generate synchronous methods for operations in addition to async. (Short Form: -{0})</source>
<target state="translated">非同期のものに加えて、操作の同期メソッドを生成します。(短縮形: -{0})</target>
Expand Down Expand Up @@ -873,4 +878,4 @@ Your credentials will be sent to the server in clear text.</source>
</trans-unit>
</body>
</file>
</xliff>
</xliff>
7 changes: 6 additions & 1 deletion src/dotnet-svcutil/lib/src/xlf/SR.ko.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -617,6 +617,11 @@ Document Identifier: '{0}'.</source>
<target state="translated">서비스 계약에 대한 코드를 생성합니다. 클라이언트 클래스는 생성되지 않습니다. (약식: -{0})</target>
<note />
</trans-unit>
<trans-unit id="HelpSeparateFiles">
<source>Creates separate files for each type in the specified output directory. (Short Form: -{0})</source>
<target state="new">Creates separate files for each type in the specified output directory. (Short Form: -{0})</target>
Comment thread
mr-sven marked this conversation as resolved.
<note />
</trans-unit>
<trans-unit id="HelpSyncFormat">
<source>Generate synchronous methods for operations in addition to async. (Short Form: -{0})</source>
<target state="translated">비동기 외에 작업에 대한 동기 메서드를 생성합니다. (약식: -{0})</target>
Expand Down Expand Up @@ -873,4 +878,4 @@ Your credentials will be sent to the server in clear text.</source>
</trans-unit>
</body>
</file>
</xliff>
</xliff>
7 changes: 6 additions & 1 deletion src/dotnet-svcutil/lib/src/xlf/SR.pl.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -617,6 +617,11 @@ Identyfikator dokumentu: „{0}”.</target>
<target state="translated">Generuj kod dla kontraktów usług. Klasa klienta nie zostanie wygenerowana. (Krótka wersja: —{0})</target>
<note />
</trans-unit>
<trans-unit id="HelpSeparateFiles">
<source>Creates separate files for each type in the specified output directory. (Short Form: -{0})</source>
<target state="new">Creates separate files for each type in the specified output directory. (Short Form: -{0})</target>
Comment thread
mr-sven marked this conversation as resolved.
<note />
</trans-unit>
<trans-unit id="HelpSyncFormat">
<source>Generate synchronous methods for operations in addition to async. (Short Form: -{0})</source>
<target state="translated">Generuj metody synchroniczne dla operacji, oprócz metod asynchronicznych. (Krótka forma: -{0})</target>
Expand Down Expand Up @@ -873,4 +878,4 @@ Twoje poświadczenia zostaną wysłane do serwera jako zwykły tekst.</target>
</trans-unit>
</body>
</file>
</xliff>
</xliff>
7 changes: 6 additions & 1 deletion src/dotnet-svcutil/lib/src/xlf/SR.pt-BR.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -617,6 +617,11 @@ Identificador do Documento: '{0}'.</target>
<target state="translated">Gerar código para Contratos de Serviço. A classe de cliente não será gerada. (Forma resumida: -{0})</target>
<note />
</trans-unit>
<trans-unit id="HelpSeparateFiles">
<source>Creates separate files for each type in the specified output directory. (Short Form: -{0})</source>
<target state="new">Creates separate files for each type in the specified output directory. (Short Form: -{0})</target>
Comment thread
mr-sven marked this conversation as resolved.
<note />
</trans-unit>
<trans-unit id="HelpSyncFormat">
<source>Generate synchronous methods for operations in addition to async. (Short Form: -{0})</source>
<target state="translated">Gere métodos síncronos para operações, além de assíncronos. (Forma Abreviada: -{0})</target>
Expand Down Expand Up @@ -873,4 +878,4 @@ As credenciais serão enviadas para o servidor em texto não criptografado.</tar
</trans-unit>
</body>
</file>
</xliff>
</xliff>
7 changes: 6 additions & 1 deletion src/dotnet-svcutil/lib/src/xlf/SR.ru.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -617,6 +617,11 @@ Document Identifier: '{0}'.</source>
<target state="translated">Создание кода для контрактов на предоставление услуг. Класс клиента не будет создан. (Короткая форма: -{0})</target>
<note />
</trans-unit>
<trans-unit id="HelpSeparateFiles">
<source>Creates separate files for each type in the specified output directory. (Short Form: -{0})</source>
<target state="new">Creates separate files for each type in the specified output directory. (Short Form: -{0})</target>
Comment thread
mr-sven marked this conversation as resolved.
<note />
</trans-unit>
<trans-unit id="HelpSyncFormat">
<source>Generate synchronous methods for operations in addition to async. (Short Form: -{0})</source>
<target state="translated">Создавать синхронные методы для операций в дополнение к асинхронным. (Краткая форма: -{0})</target>
Expand Down Expand Up @@ -873,4 +878,4 @@ Your credentials will be sent to the server in clear text.</source>
</trans-unit>
</body>
</file>
</xliff>
</xliff>
7 changes: 6 additions & 1 deletion src/dotnet-svcutil/lib/src/xlf/SR.tr.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -617,6 +617,11 @@ Belge Tanımlayıcısı: '{0}'.</target>
<target state="translated">Hizmet Sözleşmeleri için kod oluşturun. İstemci sınıfı oluşturulmaz. (Kısa Biçim: -{0})</target>
<note />
</trans-unit>
<trans-unit id="HelpSeparateFiles">
<source>Creates separate files for each type in the specified output directory. (Short Form: -{0})</source>
<target state="new">Creates separate files for each type in the specified output directory. (Short Form: -{0})</target>
Comment thread
mr-sven marked this conversation as resolved.
<note />
</trans-unit>
<trans-unit id="HelpSyncFormat">
<source>Generate synchronous methods for operations in addition to async. (Short Form: -{0})</source>
<target state="translated">İşlemler için zaman uyumsuz yöntemlerin yanı sıra zaman uyumlu yöntemler oluştur. (Kısa Biçim: -{0})</target>
Expand Down Expand Up @@ -873,4 +878,4 @@ Kimlik bilgileriniz sunucuya düz metin olarak gönderilecek.</target>
</trans-unit>
</body>
</file>
</xliff>
</xliff>
7 changes: 6 additions & 1 deletion src/dotnet-svcutil/lib/src/xlf/SR.zh-Hans.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -617,6 +617,11 @@ Document Identifier: '{0}'.</source>
<target state="translated">为服务协定生成代码。将不会生成客户端类。(缩写: -{0})</target>
<note />
</trans-unit>
<trans-unit id="HelpSeparateFiles">
<source>Creates separate files for each type in the specified output directory. (Short Form: -{0})</source>
<target state="new">Creates separate files for each type in the specified output directory. (Short Form: -{0})</target>
Comment thread
mr-sven marked this conversation as resolved.
<note />
</trans-unit>
<trans-unit id="HelpSyncFormat">
<source>Generate synchronous methods for operations in addition to async. (Short Form: -{0})</source>
<target state="translated">为除异步以外的操作生成同步方法。(缩写: -{0})</target>
Expand Down Expand Up @@ -873,4 +878,4 @@ Your credentials will be sent to the server in clear text.</source>
</trans-unit>
</body>
</file>
</xliff>
</xliff>
Loading