diff --git a/AutomaticInterface/AutomaticInterface/AutomaticInterface.csproj b/AutomaticInterface/AutomaticInterface/AutomaticInterface.csproj
index f0b0404..6bdd40e 100644
--- a/AutomaticInterface/AutomaticInterface/AutomaticInterface.csproj
+++ b/AutomaticInterface/AutomaticInterface/AutomaticInterface.csproj
@@ -24,7 +24,7 @@
MIT
True
latest-Recommended
- 5.2.6
+ 5.3.0
README.md
true
1701;1702;NU5128
diff --git a/AutomaticInterface/AutomaticInterface/GeneratedSymbolDetails.cs b/AutomaticInterface/AutomaticInterface/GeneratedSymbolDetails.cs
index 258134e..27cd54f 100644
--- a/AutomaticInterface/AutomaticInterface/GeneratedSymbolDetails.cs
+++ b/AutomaticInterface/AutomaticInterface/GeneratedSymbolDetails.cs
@@ -1,3 +1,4 @@
+using System.Diagnostics;
using System.Linq;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Syntax;
@@ -16,9 +17,8 @@ ClassDeclarationSyntax classSyntax
/// to the containing namespace of the type symbol.
///
public string NamespaceName { get; } =
- PrepareValue(
+ PrepareNamespaceName(
generationAttribute,
- AutomaticInterfaceGenerator.NamespaceParameterName,
typeSymbol.ContainingNamespace.ToDisplayString()
);
@@ -78,4 +78,19 @@ private static T PrepareValue(AttributeData? generationAttribute, string key,
return defaultValue;
}
+
+ private static string PrepareNamespaceName(AttributeData? generationAttribute, string containingNamespaceName)
+ {
+ var namespacePattern = PrepareValue(
+ generationAttribute,
+ AutomaticInterfaceGenerator.NamespaceParameterName,
+ containingNamespaceName
+ );
+
+ Debug.Assert(namespacePattern != null);
+
+ var namespaceName = namespacePattern!.Replace("*", containingNamespaceName);
+
+ return namespaceName;
+ }
}
diff --git a/AutomaticInterface/AutomaticInterface/RegisterAttributesExtensions.cs b/AutomaticInterface/AutomaticInterface/RegisterAttributesExtensions.cs
index 66e0126..beee03f 100644
--- a/AutomaticInterface/AutomaticInterface/RegisterAttributesExtensions.cs
+++ b/AutomaticInterface/AutomaticInterface/RegisterAttributesExtensions.cs
@@ -32,7 +32,7 @@ internal sealed class {{AutomaticInterfaceGenerator.DefaultAttributeName}}Attrib
///
/// Use source generator to automatically create a Interface from this class
///
- /// Namespace name for the generated interface. Defaults to the same namespace as the class.
+ /// Namespace name for the generated interface. Defaults to the same namespace as the class. The '*' character may be used as a placeholder for the containing type's namespace, allowing you to specify only a prefix for the target namespace instead of its full name.
/// Interface name for the generated interface. Defaults to an interface version of the class name, e.g ExampleClass -> IExampleClass.
/// If true, the generated interface will be internal, otherwise public
internal {{AutomaticInterfaceGenerator.DefaultAttributeName}}Attribute(string {{AutomaticInterfaceGenerator.NamespaceParameterName}} = default(string), string {{AutomaticInterfaceGenerator.InterfaceParameterName}} = default(string), bool {{AutomaticInterfaceGenerator.AsInternalParameterName}} = false) { }
diff --git a/AutomaticInterface/Tests/Misc/Misc.CustomNameSpaceWithWildcardWithinBrackedNamespace.verified.txt b/AutomaticInterface/Tests/Misc/Misc.CustomNameSpaceWithWildcardWithinBrackedNamespace.verified.txt
new file mode 100644
index 0000000..ae56a17
--- /dev/null
+++ b/AutomaticInterface/Tests/Misc/Misc.CustomNameSpaceWithWildcardWithinBrackedNamespace.verified.txt
@@ -0,0 +1,18 @@
+//--------------------------------------------------------------------------------------------------
+//
+// This code was generated by a tool.
+//
+// Changes to this file may cause incorrect behavior and will be lost if the code is regenerated.
+//
+//--------------------------------------------------------------------------------------------------
+
+namespace AutomaticInterfaceExample.CustomNameSpaceSuffix
+{
+ [global::System.CodeDom.Compiler.GeneratedCode("AutomaticInterface", "")]
+ public partial interface IDemoClass
+ {
+ ///
+ int DemoMethod();
+
+ }
+}
diff --git a/AutomaticInterface/Tests/Misc/Misc.CustomNameSpaceWithWildcardWithinFileNamespace.verified.txt b/AutomaticInterface/Tests/Misc/Misc.CustomNameSpaceWithWildcardWithinFileNamespace.verified.txt
new file mode 100644
index 0000000..ae56a17
--- /dev/null
+++ b/AutomaticInterface/Tests/Misc/Misc.CustomNameSpaceWithWildcardWithinFileNamespace.verified.txt
@@ -0,0 +1,18 @@
+//--------------------------------------------------------------------------------------------------
+//
+// This code was generated by a tool.
+//
+// Changes to this file may cause incorrect behavior and will be lost if the code is regenerated.
+//
+//--------------------------------------------------------------------------------------------------
+
+namespace AutomaticInterfaceExample.CustomNameSpaceSuffix
+{
+ [global::System.CodeDom.Compiler.GeneratedCode("AutomaticInterface", "")]
+ public partial interface IDemoClass
+ {
+ ///
+ int DemoMethod();
+
+ }
+}
diff --git a/AutomaticInterface/Tests/Misc/Misc.cs b/AutomaticInterface/Tests/Misc/Misc.cs
index d1b0677..a9ace1b 100644
--- a/AutomaticInterface/Tests/Misc/Misc.cs
+++ b/AutomaticInterface/Tests/Misc/Misc.cs
@@ -365,6 +365,48 @@ class DemoClass
await Verify(Infrastructure.GenerateCode(code));
}
+
+ [Fact]
+ public async Task CustomNameSpaceWithWildcardWithinBrackedNamespace()
+ {
+ const string code = """
+
+ using AutomaticInterface;
+
+ namespace AutomaticInterfaceExample
+ {
+ [GenerateAutomaticInterface("*.CustomNameSpaceSuffix")]
+ class DemoClass
+ {
+ public int DemoMethod() => 5;
+ }
+ }
+
+ """;
+
+ await Verify(Infrastructure.GenerateCode(code));
+ }
+
+ [Fact]
+ public async Task CustomNameSpaceWithWildcardWithinFileNamespace()
+ {
+ const string code = """
+
+ using AutomaticInterface;
+
+ namespace AutomaticInterfaceExample;
+
+ [GenerateAutomaticInterface("*.CustomNameSpaceSuffix")]
+ class DemoClass
+ {
+ public int DemoMethod() => 5;
+ }
+
+ """;
+
+ await Verify(Infrastructure.GenerateCode(code));
+ }
+
[Fact]
public async Task AsInternal()
{