diff --git "a/doc/AutoInject\347\211\210\346\234\254\346\227\245\345\277\227.md" "b/doc/AutoInject\347\211\210\346\234\254\346\227\245\345\277\227.md" index 7b8cb8f..ad7fe98 100644 --- "a/doc/AutoInject\347\211\210\346\234\254\346\227\245\345\277\227.md" +++ "b/doc/AutoInject\347\211\210\346\234\254\346\227\245\345\277\227.md" @@ -2,6 +2,36 @@ ## v0.1.4 - ⚡️升级`.NET10` +- 🛠重构生成逻辑,每个项目生成自身的注入代码,由注入程序方法调用 + +```csharp +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; +using AutoInjectGenerator.Models; +// +#pragma warning disable +#nullable enable +namespace Blazor.Test +{ + /// + [global::System.CodeDom.Compiler.GeneratedCode("AutoInjectGenerator.AutoInjectContextGenerator", "0.1.4.0")] + static partial class AutoInjectContext + { + private static readonly global::System.Collections.Generic.List _includes = ["SERVER"] ; + + private static readonly global::System.Collections.Generic.List _excludes = [] ; + + + public static partial void Inject(this Microsoft.Extensions.DependencyInjection.IServiceCollection services) + { + var config = new global::AutoInjectGenerator.AutoInjectConfiguration(_excludes, _includes); + global::Blazor.Test.Client.AutoInjectModuleServices.InjectModuleServices(services, config); + global::InjectTest.AutoInjectModuleServices.InjectModuleServices(services, config); + global::TestProject1.AutoInjectModuleServices.InjectModuleServices(services, config); + } + } +} +``` ## v0.1.3 - 🛠优化分组判断,现在可以配置在不同的分组中注入相同的实例 diff --git a/src/AutoInject.Roslyn/AutoInjectContextGenerator.cs b/src/AutoInject.Roslyn/AutoInjectContextGenerator.cs index 3f88f46..679b7d0 100644 --- a/src/AutoInject.Roslyn/AutoInjectContextGenerator.cs +++ b/src/AutoInject.Roslyn/AutoInjectContextGenerator.cs @@ -11,58 +11,11 @@ namespace AutoInjectGenerator; -[Generator(LanguageNames.CSharp)] -public class AutoInjectContextGenerator : IIncrementalGenerator +//[Generator(LanguageNames.CSharp)] +public class AutoInjectContextGenerator //: IIncrementalGenerator { public void Initialize(IncrementalGeneratorInitializationContext context) { - //只能获取到当前程序集的节点 - //var ctx = context.SyntaxProvider.ForAttributeWithMetadataName( - // AutoInjectContext - // , static (node, _) => node is ClassDeclarationSyntax - // , CollectContextInfo).Collect(); - //var services = context.SyntaxProvider.ForAttributeWithMetadataName( - // AutoInject - // , static (node, _) => node is ClassDeclarationSyntax - // , CollectInjectInfo).Collect(); - - //var ctx = context.CompilationProvider.ForAttributeWithMetadataName( - // AutoInjectContext - // , static (node, _) => true - // , (ctx, _) => CollectContextInfo(ctx)).Collect(); - //var services = context.CompilationProvider.ForAttributeWithMetadataName( - // AutoInject - // , static (node, _) => true - // , (ctx, _) => CollectInjectInfo(ctx)).Collect(); - - //context.RegisterSourceOutput(context.CompilationProvider.Combine(ctx.Combine(services)), static (context, source) => - //{ - // (Compilation compilation, var Right) = source; - // (var allContext, var services) = Right; - // foreach (var item in allContext) - // { - // if (item is null) continue; - // if (!EqualityComparer.Default.Equals(item.TargetSymbol.ContainingAssembly, compilation.SourceModule.ContainingAssembly)) - // { - // continue; - // } - // if (item.Diagnostic != null) - // { - // context.ReportDiagnostic(item.Diagnostic); - // return; - // } - - // foreach (var a in services.Where(a => a?.Diagnostic is not null)) - // { - // context.ReportDiagnostic(a!.Diagnostic!); - // return; - // } - // var codefile = CreateContextCodeFile(item, services); - // context.AddSource(codefile); - // } - //}); - - context.RegisterSourceOutput(context.CompilationProvider, static (context, source) => { var allContext = source.FindByAttributeMetadataName( diff --git a/src/AutoInject.Roslyn/AutoInjectContextGeneratorHelpers.cs b/src/AutoInject.Roslyn/AutoInjectContextGeneratorHelpers.cs index 4d2675d..a4dccc5 100644 --- a/src/AutoInject.Roslyn/AutoInjectContextGeneratorHelpers.cs +++ b/src/AutoInject.Roslyn/AutoInjectContextGeneratorHelpers.cs @@ -12,9 +12,10 @@ namespace AutoInjectGenerator; internal static class AutoInjectContextGeneratorHelpers { public const string AutoInjectContext = "AutoInjectGenerator.AutoInjectContextAttribute"; - public const string AutoInjectConfiguration = "AutoInjectGenerator.AutoInjectConfiguration"; + public const string AutoInjectConfiguration = "AutoInjectGenerator.AutoInjectConfigurationAttribute"; public const string AutoInject = "AutoInjectGenerator.AutoInjectAttribute"; public const string AutoInjectSelf = "AutoInjectGenerator.AutoInjectSelfAttribute"; + public const string AutoInjectModule = "AutoInjectGenerator.AutoInjectModuleAttribute"; private static bool IsInjectSelf(AttributeData data) => data.AttributeClass?.ToDisplayString() == AutoInjectSelf; // new ServiceDescriptor() @@ -165,7 +166,62 @@ bool HasDifferentScopedInSameMemberShip() .Any(g => g.Select(s => s.Scoped).Distinct().Count() > 1); } } + public static AutoInjectInfo CollectInjectInfo(INamedTypeSymbol classSymbol, SyntaxNode targetNode) + { + var info = new AutoInjectInfo(classSymbol); + foreach (var a in classSymbol.GetAttributes(AutoInject, true)) + { + if (!a.GetNamedValue("LifeTime", out var injectType)) + { + injectType = 1; + } + var scoped = FormatInjectType(injectType); + + string serviceType; + if (IsInjectSelf(a)) + { + serviceType = info.Implement; + } + else if(a.GetNamedValue("ServiceType", out var t) && t is INamedTypeSymbol type) + { + serviceType = type.ToDisplayString(); + if (!classSymbol.AllInterfaces.Contains(type) + && !SymbolEqualityComparer.Default.Equals(classSymbol, type) + && !classSymbol.IsSubClassOf(type)) + { + info.Diagnostic = DiagnosticDefinitions.AIG00003(serviceType, info.Implement, targetNode.GetLocation()); + return info; + } + } + // 获取到的Interfaces跟AllInterfaces一样 + else if (classSymbol.Interfaces.Length >= 1) + { + serviceType = classSymbol.Interfaces[0].ToDisplayString(); + } + else + { + serviceType = info.Implement; + } + + _ = a.GetNamedValue("ServiceKey", out var serviceKey); + _ = a.GetNamedValue("Group", out var group); + info.Services.Add(new RegisterServiceInfo(scoped, serviceType, serviceKey, group)); + } + + if (HasDifferentScopedInSameMemberShip()) + { + info.Diagnostic = DiagnosticDefinitions.AIG00004(targetNode.GetLocation()); + } + return info; + + bool HasDifferentScopedInSameMemberShip() + { + return info.Services.Where(s => s.MemberShip != null) + .GroupBy(s => s.MemberShip) + .Any(g => g.Select(s => s.Scoped).Distinct().Count() > 1); + } + } public static CodeFile? CreateContextCodeFile(AutoInjectContextInfo context, IEnumerable items) { var classSymbol = context.TargetSymbol; @@ -269,7 +325,7 @@ private static IEnumerable CreateRegisterStatement(AutoInjectContextInfo } } - + yield return ""; static bool ShouldRegister(AutoInjectContextInfo context, string? group) diff --git a/src/AutoInject.Roslyn/AutoInjectEntryGenerator.cs b/src/AutoInject.Roslyn/AutoInjectEntryGenerator.cs new file mode 100644 index 0000000..9769511 --- /dev/null +++ b/src/AutoInject.Roslyn/AutoInjectEntryGenerator.cs @@ -0,0 +1,100 @@ +using Generators.Shared; +using Generators.Shared.Builder; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp.Syntax; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using static AutoInjectGenerator.AutoInjectContextGeneratorHelpers; +namespace AutoInjectGenerator; + +[Generator(LanguageNames.CSharp)] +public class AutoInjectEntryGenerator : IIncrementalGenerator +{ + public void Initialize(IncrementalGeneratorInitializationContext context) + { + var value = context.SyntaxProvider.ForAttributeWithMetadataName(AutoInjectContext + , static (node, _) => node is ClassDeclarationSyntax + , static (ctx, _) => CollectContextInfo(ctx, _)); + context.RegisterSourceOutput(value, static (spc, source) => + { + var target = source.TargetSymbol; + var asm = target.ContainingAssembly; + var modules = new List(); + if (asm.GlobalNamespace is not null) + { + modules.AddRange(asm.GlobalNamespace.GetAllMembers(i => i is INamedTypeSymbol m && m.HasAttribute(AutoInjectModule))); + } + foreach (var item in asm.Modules) + { + foreach (var referencedAssembly in item.ReferencedAssemblySymbols) + { + if (referencedAssembly.Name.StartsWith("System.") || referencedAssembly.Name.StartsWith("Microsoft.")) + continue; + + if (referencedAssembly.GlobalNamespace is null) continue; + modules.AddRange(referencedAssembly.GlobalNamespace.GetAllMembers(i => i is INamedTypeSymbol m && m.HasAttribute(AutoInjectModule))); + } + } + var file = CreateCodeFile(source, modules); +#if DEBUG + var sss = file?.ToString(); +#endif + spc.AddSource(file); + }); + } + + private static CodeFile? CreateCodeFile(AutoInjectContextInfo context, List modules) + { + var classSymbol = context.TargetSymbol; + var className = context.ClassName; + var methodSymbol = context.MethodSymbol!; + var gn = NamespaceBuilder.Default.Namespace(classSymbol.ContainingNamespace.ToDisplayString()); + var gclass = ClassBuilder.Default + .ClassName(className) + .AddGeneratedCodeAttribute(typeof(AutoInjectContextGenerator)) + .Modifiers("static partial"); + + var serviceName = methodSymbol.Parameters.First(p => + p.Type.ToDisplayString().Contains("Microsoft.Extensions.DependencyInjection.IServiceCollection")).Name; + + var includeField = FieldBuilder.Default + .Modifiers("private static readonly") + .MemberType("global::System.Collections.Generic.List") + .FieldName("_includes") + .InitializeWith($"[{string.Join(", ", context.Includes.Select(s => $"\"{s}\""))}] "); + var excludeField = FieldBuilder.Default + .Modifiers("private static readonly") + .MemberType("global::System.Collections.Generic.List") + .FieldName("_excludes") + .InitializeWith($"[{string.Join(", ", context.Excludes.Select(s => $"\"{s}\""))}] "); + + var cm = MethodBuilder.Default.Partial(methodSymbol); + { + // 创建配置 + List methodBody = [ + "var config = new global::AutoInjectGenerator.AutoInjectConfiguration(_excludes, _includes)", + //$"global::AutoInjectGenerator.AutoInjectManager.ApplyProjectServices({serviceName}, config)" + ]; + foreach (var item in modules) + { + methodBody.Add($"global::{item.ContainingAssembly.Name}.AutoInjectModuleServices.InjectModuleServices({serviceName}, config)"); + } + cm.AddBody([.. methodBody]); + } + gclass.AddMembers(includeField); + gclass.AddMembers(excludeField); + gclass.AddMembers(cm); + + var file = CodeFile.New($"{className}.AutoInject.g.cs") + .AddUsings("using Microsoft.Extensions.DependencyInjection;") + .AddUsings("using Microsoft.Extensions.DependencyInjection.Extensions;") + .AddUsings("using AutoInjectGenerator.Models;") + .AddMembers(gn.AddMembers(gclass)); + +#if DEBUG + var ss = file.ToString(); +#endif + return file; + } +} diff --git a/src/AutoInject.Roslyn/AutoInjectModuleGenerator.cs b/src/AutoInject.Roslyn/AutoInjectModuleGenerator.cs new file mode 100644 index 0000000..bb402c5 --- /dev/null +++ b/src/AutoInject.Roslyn/AutoInjectModuleGenerator.cs @@ -0,0 +1,173 @@ +using Generators.Shared; +using Generators.Shared.Builder; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp.Syntax; +using System; +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Linq; +using System.Text; +using static AutoInjectGenerator.AutoInjectContextGeneratorHelpers; +namespace AutoInjectGenerator; + +[Generator(LanguageNames.CSharp)] +public class AutoInjectModuleGenerator : IIncrementalGenerator +{ + public void Initialize(IncrementalGeneratorInitializationContext context) + { + //var vvv = context.SyntaxProvider.ForAttributeWithMetadataName("AutoInjectGenerator.AutoInjectAttribute" + // , static (node, _) => node is ClassDeclarationSyntax + // , static (ctx, _) => CollectInjectInfo(ctx)).Collect(); + + var targets = context.SyntaxProvider.CreateSyntaxProvider( + static (node, _) => node is ClassDeclarationSyntax cs && cs.AttributeLists.Count > 0, + static (ctx, _) => + { + var classDecl = (ClassDeclarationSyntax)ctx.Node; + var semanticModel = ctx.SemanticModel; + var classSymbol = (INamedTypeSymbol)semanticModel.GetDeclaredSymbol(classDecl)!; + if (classSymbol.HasAttribute(AutoInject, true)) + { + return CollectInjectInfo(classSymbol, ctx.Node); + } + return null; + }).Where(static i => i is not null)!.Collect(); + context.RegisterSourceOutput(context.CompilationProvider.Combine(targets), static (spc, source) => + { + var (compilation, services) = source; + var asm = compilation.Assembly; + var codeFile = CreateModuleServiceInitClass(asm, services!); + if (codeFile is not null) + { +#if DEBUG + var sss = codeFile.ToString(); +#endif + spc.AddSource(codeFile); + } + }); + } + + private static CodeFile? CreateModuleServiceInitClass(IAssemblySymbol asm, ImmutableArray services) + { + var gn = NamespaceBuilder.Default.Namespace(asm.Name); + var gclass = ClassBuilder.Default.ClassName($"AutoInjectModuleServices") + .Attribute(AutoInjectModule) + .AddGeneratedCodeAttribute(typeof(AutoInjectModuleGenerator)); + + gclass.AddMembers([.. InitMethods(asm, services)]); + return CodeFile.New($"{asm.SafeMetaName()}.AutoInject.ModuleServices.g.cs").AddUsings("using Microsoft.Extensions.DependencyInjection;") + .AddUsings("using Microsoft.Extensions.DependencyInjection.Extensions;") + .AddUsings("using AutoInjectGenerator.Models;") + .AddUsings("using AutoInjectGenerator;") + .AddMembers(gn.AddMembers(gclass)); + + } + const string SD = "AutoInjectServiceDescriptor"; + private static IEnumerable InitMethods(IAssemblySymbol asm, ImmutableArray services) + { + // global::System.Runtime.CompilerServices.ModuleInitializerAttribute + var serviceName = "services"; + var configName = "config"; + var body = new List(); + foreach (var info in services) + { + if (info is null || info.Services.Count == 0) + { + body.Add($"// No services to register for {info?.Implement}"); + continue; + } + body.Add($"// {info.Implement} 类型的相关注册"); + string implement = $"typeof({info.Implement})"; + var groups = info.Services.GroupBy(r => r.MemberShip) + .Select(g => new { g.Key, Values = g.Select(gi => gi).ToArray() }).ToArray(); + foreach (var group in groups) + { + var groupName = group.Key; + var item = group.Values; + if (string.IsNullOrWhiteSpace(groupName)) + { + body.AddRange([.. RegisterStatements(info, item, serviceName, implement)]); + } + else + { + var checkGroup = IfStatement.Default.If($"{configName}.ShouldInject(\"{groupName}\")") + .AddStatement([.. RegisterStatements(info, item, serviceName, implement)]); + + body.Add(checkGroup); + } + + } + } + //var initMethodName = $"{asm.SafeMetaName()}_Initialize"; + yield return MethodBuilder.Default.MethodName("InjectModuleServices") + .Modifiers("public static") + .AddParameter("IServiceCollection services", "AutoInjectConfiguration config") + .AddGeneratedCodeAttribute(typeof(AutoInjectModuleGenerator)) + .AddBody([.. body]); + + + // 模块初始化方法 + //yield return MethodBuilder.Default.MethodName($"{asm.SafeMetaName()}_ModuleInit") + //.Modifiers("public static") + //.Attribute("global::System.Runtime.CompilerServices.ModuleInitializerAttribute") + //.AddGeneratedCodeAttribute(typeof(AutoInjectModuleGenerator)) + //.Lambda($"global::AutoInjectGenerator.AutoInjectManager.RegisterProjectServices(\"{asm.Name}\", {initMethodName})"); + + static IEnumerable RegisterStatements(AutoInjectInfo info, RegisterServiceInfo[] item, string serviceName, string implement) + { + // 每个分组中的Scoped是一样的,前面已经处理过 + if (item.Length == 1) + { + var r = item[0]; + yield return (DoCreate(serviceName, r.ServiceType, implement, r.Scoped, r.Key)); + } + else + { + // 多次注入同一个服务,但是没有注入自身 + var self = item.FirstOrDefault(s => s.ServiceType == info.Implement); + if (self is null) + { + // 提供默认的自身注入 + yield return (DoCreate(serviceName, info.Implement, implement, item[0].Scoped, null, true)); + } + foreach (var r in item) + { + if (r.ServiceType == info.Implement) + { + // 显式注入自身,说明前面的self不为null + yield return (DoCreate(serviceName, r.ServiceType, implement, r.Scoped, r.Key, true)); + } + else + { + var factoryExpression = $"p => p.GetRequiredService<{info.Implement}>()"; + if (r.Key is not null) + { + factoryExpression = $"(p, k) => p.GetRequiredKeyedService<{info.Implement}>(k)"; + if (self is null || r.Key != self.Key) + { + // 注入自身 + yield return (DoCreate(serviceName, info.Implement, implement, r.Scoped, r.Key)); + } + } + // 注入接口 + yield return (DoCreate(serviceName, r.ServiceType, factoryExpression, r.Scoped, r.Key, factoryReturnType: $", {implement}")); + } + } + } + } + + + static string DoCreate(string serviceName, string serviceType, string implement, string scoped, string? key, bool tryadd = false, string? factoryReturnType = "") + { + var method = tryadd ? "TryAdd" : "Add"; + if (key is not null) + { + return $"""{serviceName}.{method}(new {SD}(typeof({serviceType}),"{key}", {implement}, {scoped}{factoryReturnType}))"""; + } + else + { + return $"{serviceName}.{method}(new {SD}(typeof({serviceType}), {implement}, {scoped}{factoryReturnType}))"; + } + } + } +} diff --git a/src/AutoInjectGenerator/Attributes/AutoInjectAttribute.cs b/src/AutoInjectGenerator/Attributes/AutoInjectAttribute.cs index f512492..3c48b36 100644 --- a/src/AutoInjectGenerator/Attributes/AutoInjectAttribute.cs +++ b/src/AutoInjectGenerator/Attributes/AutoInjectAttribute.cs @@ -22,7 +22,7 @@ public class AutoInjectAttribute : Attribute /// public Type? ServiceType { get; set; } /// - /// 配置所属组别, 适用于或者 + /// 配置所属组别, 适用于或者 /// public string? Group { get; set; } /// diff --git a/src/AutoInjectGenerator/Attributes/AutoInjectConfiguration.cs b/src/AutoInjectGenerator/Attributes/AutoInjectConfigurationAttribute.cs similarity index 90% rename from src/AutoInjectGenerator/Attributes/AutoInjectConfiguration.cs rename to src/AutoInjectGenerator/Attributes/AutoInjectConfigurationAttribute.cs index 613a662..22eb38d 100644 --- a/src/AutoInjectGenerator/Attributes/AutoInjectConfiguration.cs +++ b/src/AutoInjectGenerator/Attributes/AutoInjectConfigurationAttribute.cs @@ -6,7 +6,7 @@ namespace AutoInjectGenerator; /// 自动注入分组配置 /// [AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = false)] -public class AutoInjectConfiguration : Attribute +public class AutoInjectConfigurationAttribute : Attribute { /// /// 忽略的值等于的项 diff --git a/src/AutoInjectGenerator/Attributes/AutoInjectModuleAttribute.cs b/src/AutoInjectGenerator/Attributes/AutoInjectModuleAttribute.cs new file mode 100644 index 0000000..9f4d435 --- /dev/null +++ b/src/AutoInjectGenerator/Attributes/AutoInjectModuleAttribute.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace AutoInjectGenerator; + +/// +/// Specifies that the attributed class is an auto-injectable module for dependency injection frameworks. +/// +/// Apply this attribute to a class to indicate that it should be automatically discovered and registered +/// as a module by compatible dependency injection containers. This attribute is typically used in frameworks that +/// support convention-based module registration. +[AttributeUsage(AttributeTargets.Class)] +public class AutoInjectModuleAttribute : Attribute +{ +} diff --git a/src/AutoInjectGenerator/AutoInjectManager.cs b/src/AutoInjectGenerator/AutoInjectManager.cs new file mode 100644 index 0000000..9699b18 --- /dev/null +++ b/src/AutoInjectGenerator/AutoInjectManager.cs @@ -0,0 +1,73 @@ +using Microsoft.Extensions.DependencyInjection; +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Runtime.CompilerServices; +using System.Text; + +namespace AutoInjectGenerator; + +/// +/// +/// +public readonly struct AutoInjectConfiguration(List ExcludeGroups, List IncludeGroups) +{ + /// + /// + /// + /// + /// + public readonly bool ShouldInject(string group) + { + if (string.IsNullOrWhiteSpace(group)) + { + return true; + } + // 没有配置规则,全部注入 + if (IncludeGroups.Count == 0 && ExcludeGroups.Count == 0) + { + return true; + } + /* + * 配置了Group属性 + * 1. 不在excludes中才能注册 + * 2. 存在includes中才能注册 + */ + if (ExcludeGroups.Contains(group) || !IncludeGroups.Contains(group)) + { + return false; + } + return true; + } +} + +/// +/// +/// +[Obsolete] +public class AutoInjectManager +{ + private static readonly ConcurrentDictionary> projectServices = []; + /// + /// + /// + /// + /// + public static void RegisterProjectServices(string projectName, Action registerAction) + { + projectServices.TryAdd(projectName, registerAction); + } + /// + /// + /// + /// + /// + public static void ApplyProjectServices(IServiceCollection services, AutoInjectConfiguration config) + { + foreach (var item in projectServices.Values) + { + item.Invoke(services, config); + } + } +} + diff --git a/src/AutoInjectGenerator/Versions.props b/src/AutoInjectGenerator/Versions.props index 50bc64d..0e0b75f 100644 --- a/src/AutoInjectGenerator/Versions.props +++ b/src/AutoInjectGenerator/Versions.props @@ -1,6 +1,6 @@  - 0.1.4 + 0.1.4-pre $(BuildVersion) $(BuildVersion) diff --git a/src/Blazor.Test/Blazor.Test.Client/AutoWasmInjectContext.cs b/src/Blazor.Test/Blazor.Test.Client/AutoWasmInjectContext.cs index 7216ad4..667e0dd 100644 --- a/src/Blazor.Test/Blazor.Test.Client/AutoWasmInjectContext.cs +++ b/src/Blazor.Test/Blazor.Test.Client/AutoWasmInjectContext.cs @@ -6,7 +6,7 @@ namespace Blazor.Test.Client [AutoInjectContext] public static partial class AutoWasmInjectContext { - [AutoInjectConfiguration(Include = "WASM")] + [AutoInjectConfigurationAttribute(Include = "WASM")] public static partial void AutoWasm(this IServiceCollection services); } } diff --git a/src/Blazor.Test/Blazor.Test.Client/Blazor.Test.Client.csproj b/src/Blazor.Test/Blazor.Test.Client/Blazor.Test.Client.csproj index 0af4710..d3e44bf 100644 --- a/src/Blazor.Test/Blazor.Test.Client/Blazor.Test.Client.csproj +++ b/src/Blazor.Test/Blazor.Test.Client/Blazor.Test.Client.csproj @@ -26,6 +26,7 @@ + diff --git a/src/Blazor.Test/Blazor.Test/AutoInjectContext.cs b/src/Blazor.Test/Blazor.Test/AutoInjectContext.cs index e93241a..e346333 100644 --- a/src/Blazor.Test/Blazor.Test/AutoInjectContext.cs +++ b/src/Blazor.Test/Blazor.Test/AutoInjectContext.cs @@ -5,14 +5,14 @@ namespace Blazor.Test [AutoInjectContext] public static partial class AutoInjectContext { - [AutoInjectConfiguration(Include = "SERVER")] + [AutoInjectConfigurationAttribute(Include = "SERVER")] public static partial void Inject(this IServiceCollection services); } [AutoInjectContext] public static partial class AutoInjectContextHybrid { - [AutoInjectConfiguration(Include = "HYBRID")] + [AutoInjectConfigurationAttribute(Include = "HYBRID")] public static partial void InjectHybrid(this IServiceCollection services); } } diff --git a/src/Blazor.Test/Blazor.Test/Blazor.Test.csproj b/src/Blazor.Test/Blazor.Test/Blazor.Test.csproj index 7bb1539..a0c066d 100644 --- a/src/Blazor.Test/Blazor.Test/Blazor.Test.csproj +++ b/src/Blazor.Test/Blazor.Test/Blazor.Test.csproj @@ -9,11 +9,10 @@ - + - diff --git a/src/InjectTest/InjectTestClass.cs b/src/InjectTest/InjectTestClass.cs index 238d173..b75c353 100644 --- a/src/InjectTest/InjectTestClass.cs +++ b/src/InjectTest/InjectTestClass.cs @@ -23,7 +23,7 @@ public class Base : IDisposable { public void Dispose() { - + } } @@ -58,3 +58,4 @@ public class FileService } } + diff --git a/src/Shared b/src/Shared index 753bbc6..98d992a 160000 --- a/src/Shared +++ b/src/Shared @@ -1 +1 @@ -Subproject commit 753bbc69e3ec48241e30ab9edc0d2ef97cabfadd +Subproject commit 98d992ad3094600fee3a97522608c99a9667c1d1 diff --git a/src/TestProject1/Models/User.cs b/src/TestProject1/Models/User.cs index 7bc3a2b..70bcb9e 100644 --- a/src/TestProject1/Models/User.cs +++ b/src/TestProject1/Models/User.cs @@ -7,6 +7,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; +using AutoInjectGenerator; namespace TestProject1.Models { @@ -24,6 +25,7 @@ public interface IPower } // [GenMapper] + [AutoInject] public partial class Power : IPower { public string? PowerId { get; set; } diff --git a/src/TestProject1/TestProject1.csproj b/src/TestProject1/TestProject1.csproj index e1e9b10..aca980a 100644 --- a/src/TestProject1/TestProject1.csproj +++ b/src/TestProject1/TestProject1.csproj @@ -1,30 +1,32 @@ - - net8.0 - enable - enable + + net8.0 + enable + enable - false - true - + false + true + - - - - - - + + + + + + - - - - - - + + + + + + + + - - - + + +