diff --git a/samples/Blazor/Server/Hubs/MainHub.cs b/samples/Blazor/Server/Hubs/MainHub.cs
index b3b6621..7f799f6 100644
--- a/samples/Blazor/Server/Hubs/MainHub.cs
+++ b/samples/Blazor/Server/Hubs/MainHub.cs
@@ -1,6 +1,7 @@
using BlazorSignalR.Server.SignalRModules;
using ChatModule.Server;
using SignalR.Modules;
+using System;
using WeatherModule.Server;
namespace BlazorSignalR.Server.Hubs
@@ -10,5 +11,9 @@ namespace BlazorSignalR.Server.Hubs
[SignalRModuleHub(typeof(CounterHub))]
public partial class MainHub : ModulesEntryHub
{
+ public MainHub(IServiceProvider provider)
+ : base(provider)
+ {
+ }
}
}
diff --git a/src/SignalR.Modules.Generator/HubGenerator.cs b/src/SignalR.Modules.Generator/HubGenerator.cs
index 7ffb860..06eb977 100644
--- a/src/SignalR.Modules.Generator/HubGenerator.cs
+++ b/src/SignalR.Modules.Generator/HubGenerator.cs
@@ -1,10 +1,14 @@
-using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
+using System;
using System.Collections.Generic;
+using System.Diagnostics;
using System.Linq;
using System.Text;
+#nullable enable
+
namespace SignalR.Modules.Generator
{
[Generator]
@@ -14,16 +18,23 @@ public class HubGenerator : ISourceGenerator
private const string AttributeName = "SignalRModuleHubAttribute";
private const string AttributeFullName = AttributeNamespace + "." + AttributeName;
private const string AutoGeneratedFileHeader =
-@"//------------------------------------------------------------------------------
-//
-// This code was generated by the SignalR.Modules Source Generator.
-//
+@"//------------------------------------------------------------------------------
+//
+// This code was generated by the SignalR.Modules Source Generator.
+//
//------------------------------------------------------------------------------";
public void Initialize(GeneratorInitializationContext context)
{
// Register a syntax receiver that will be created for each generation pass
context.RegisterForSyntaxNotifications(() => new SyntaxReceiver());
+
+#if DEBUG
+ if (!Debugger.IsAttached)
+ {
+ Debugger.Launch();
+ }
+#endif
}
public void Execute(GeneratorExecutionContext context)
@@ -94,14 +105,50 @@ public partial class {entryHubTypeSymbol.Name}
}
source.Append(@"
- }
+ }
}");
return source.ToString();
}
private string ProcessModuleHubMethod(INamedTypeSymbol moduleHubTypeSymbol, IMethodSymbol methodSymbol)
{
+ var attributes = methodSymbol.GetAttributes();
+ var constructedAttributes = attributes.Where(x => x.ConstructorArguments.Any()).ToList();
+ var namedArgumentAttributes = attributes.Where(x => x.NamedArguments.Any()).ToList();
+
+ var ctorAttributesString = string.Join(Environment.NewLine, constructedAttributes
+ .Select(x =>
+ {
+ var ctorArgumentsString = string.Join(",", x.ConstructorArguments
+ .Select(y => y.Kind switch
+ {
+ TypedConstantKind.Enum => $"{y.Type.Name}.{y.Value}",
+ _ when y.Type.SpecialType == SpecialType.System_String => $"\"{y.Value}\"",
+ _ => y.Value
+ })
+ );
+ return $"[{x.AttributeClass.ContainingNamespace.ToDisplayString()}.{x.AttributeClass.Name.Replace("Attribute", string.Empty)}({ctorArgumentsString})]";
+ })
+ );
+
+ var namedAttributesString = string.Join(Environment.NewLine, namedArgumentAttributes
+ .Select(x =>
+ {
+ var namedArgumentsString = string.Join(",", x.NamedArguments
+ .Select(y => $@"{y.Key} = {y.Value.Kind switch
+ {
+ TypedConstantKind.Enum => $"{y.Value.Type.Name}.{y.Value}",
+ _ when y.Value.Type.SpecialType == SpecialType.System_String => $"\"{y.Value.Value}\"",
+ _ => y.Value.Value
+ }}")
+ );
+ return $"[{x.AttributeClass.ContainingNamespace.ToDisplayString()}.{x.AttributeClass.Name.Replace("Attribute", string.Empty)}({namedArgumentsString})]";
+ })
+ );
+
return $@"
+ {ctorAttributesString}
+ {namedAttributesString}
public {(methodSymbol.ReturnsVoid ? string.Empty : methodSymbol.ReturnType.ToDisplayString())} {moduleHubTypeSymbol.Name}_{methodSymbol.Name}({string.Join(", ", methodSymbol.Parameters.Select(p => $"{p.Type.ToDisplayString()} {p.Name}"))})
{{
var hub = ServiceProvider.GetRequiredService<{moduleHubTypeSymbol.ToDisplayString()}>();
@@ -126,7 +173,7 @@ private string ProcessHubClientClass(INamedTypeSymbol entryHubTypeSymbol, INamed
namespace {namespaceName}
{{
- public class {className} : ClientProxy<{moduleHubTypeSymbol.Name}>, {typedClientInterface.Name}
+ public class {className} : ClientProxy<{moduleHubTypeSymbol.ToDisplayString()}>, {typedClientInterface.ToDisplayString()}
{{
public {className}(IClientProxy clientProxy)
: base(clientProxy)
@@ -143,7 +190,7 @@ public class {className} : ClientProxy<{moduleHubTypeSymbol.Name}>, {typedClient
}
source.Append(@"
- }
+ }
}");
return source.ToString();
}
@@ -153,7 +200,7 @@ private string ProcessHubClientMethod(IMethodSymbol methodSymbol)
return $@"
public Task {methodSymbol.Name}({string.Join(", ", methodSymbol.Parameters.Select(p => $"{p.Type.ToDisplayString()} {p.Name}"))})
{{
- return SendAsync(""{methodSymbol.Name}"", new[] {{ {string.Join(", ", methodSymbol.Parameters.Select(p => p.Name))} }});
+ return SendAsync(""{methodSymbol.Name}"", new object[] {{ {string.Join(", ", methodSymbol.Parameters.Select(p => p.Name))} }});
}}";
}
@@ -291,7 +338,7 @@ protected Task ModuleHubsOnDisconnectedAsync(Exception exception)
}
source.Append(@"
- }
+ }
}");
return source.ToString();
}
diff --git a/src/SignalR.Modules/ModulesEntryHub.cs b/src/SignalR.Modules/ModulesEntryHub.cs
index 9a19618..7ea8964 100644
--- a/src/SignalR.Modules/ModulesEntryHub.cs
+++ b/src/SignalR.Modules/ModulesEntryHub.cs
@@ -1,5 +1,6 @@
using Microsoft.AspNetCore.SignalR;
using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Logging.Abstractions;
using System;
namespace SignalR.Modules
@@ -16,6 +17,12 @@ public ModulesEntryHub(ILogger logger, IServiceProvider serviceProvider)
ServiceProvider = serviceProvider;
}
+ public ModulesEntryHub(IServiceProvider serviceProvider)
+ {
+ Logger = NullLogger.Instance;
+ ServiceProvider = serviceProvider;
+ }
+
protected void InitModuleHub(TModuleHub hub)
where TModuleHub : ModuleHub
{