ShadowCode.Injection 2.0.4

dotnet add package ShadowCode.Injection --version 2.0.4
                    
NuGet\Install-Package ShadowCode.Injection -Version 2.0.4
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="ShadowCode.Injection" Version="2.0.4">
  <PrivateAssets>all</PrivateAssets>
  <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="ShadowCode.Injection" Version="2.0.4" />
                    
Directory.Packages.props
<PackageReference Include="ShadowCode.Injection">
  <PrivateAssets>all</PrivateAssets>
  <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add ShadowCode.Injection --version 2.0.4
                    
#r "nuget: ShadowCode.Injection, 2.0.4"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#addin nuget:?package=ShadowCode.Injection&version=2.0.4
                    
Install as a Cake Addin
#tool nuget:?package=ShadowCode.Injection&version=2.0.4
                    
Install as a Cake Tool

ShadowCode.Injection

基本设置

  • nuget

PM

PM> Install-Package ShadowCode.Injection
PM> Install-Package Microsoft.Extensions.Options.ConfigurationExtensions
PM> Install-Package Microsoft.Extensions.DependencyInjection
PM> Install-Package Microsoft.Extensions.Configuration.Json

Project

<ItemGroup>
    <PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="*" />
    <PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="*" />
    <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="*" />       

    <PackageReference Include="ShadowCode.Injection" Version="*">
        <PrivateAssets>all</PrivateAssets>
        <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
    </PackageReference>
</ItemGroup>
  • global using

global using Microsoft.Extensions.DependencyInjection;
global using ShadowCode;

AddService

生成器会根据项目的空间名 RootNamespace 生成对应的扩展方法(默认情况为项目名称)

新建项目 Project1

namespace Project1;

interface IService<T> { }

[AddService(ServiceLifetime.Singleton)]
[AddService(ServiceLifetime.Transient)]
[AddService(ServiceLifetime.Scoped)]
class MyClass { }

生成代码如下

namespace Project1;
public static partial class ShadowCodeInjectionExtensions
{
    // 扩展方法 Use{项目名称} 可自定义。
    public static IServiceCollection UseProject1(this IServiceCollection service, IConfigurationManager? config = null)
    {
        UseStart(service, config);

        // --------------- 注册服务
        service.AddSingleton(typeof(Project1.MyClass));
        service.AddTransient(typeof(Project1.MyClass));
        service.AddScoped(typeof(Project1.MyClass));
        // --------------- 注册服务

        UseEnd(service, config);
        return service;
    }    

    // 预留用户使用
    static partial void UseStart(IServiceCollection service, IConfigurationManager? config);
    static partial void UseEnd(IServiceCollection service, IConfigurationManager? config);    
}

  • Asp.Net 中使用
var builder = WebApplication.CreateBuilder(args);
builder.Services.UseProject1(builder.Configuration);
var app = builder.Build();
  • 命令行 中使用
ConfigurationManager configurationManager = new();
ServiceCollection serviceCollection = new();
var service = serviceCollection
    .UseProject1(configurationManager)
    .BuildServiceProvider();
  • 自定义扩展方法名称(可选)

某些情况下需要重启IDE才能生效!项目未单独Nuget的情况下也会失效!

<PropertyGroup>
    
    <ShadowCode_Injection_UseMethodName>UseXXXXX</ShadowCode_Injection_UseMethodName>
</PropertyGroup>

生成代码如下

namespace Project1;
public static partial class ShadowCodeInjectionExtensions
{
    public static IServiceCollection UseXXXXX(this IServiceCollection service, IConfigurationManager config)
    {
       ...
    }  
}
  • 泛型类

    1. 默认类型
[AddService(ServiceLifetime.Scoped)]
class MyClass<T> {}

生成代码

service.AddScoped(typeof(Project1.MyClass<>));
    1. 泛型服务
[AddService(ServiceLifetime.Scoped, ServiceType = typeof(IService<>))]
class MyClass<T> : IService<T> { }

生成代码

var serviceType = typeof(Project1.IService<>);
var implementType = typeof(Project1.MyClass<>);
service.AddScoped(serviceType, implementType);
    1. 泛型实参服务
[AddService<IService<string>>(ServiceLifetime.Scoped)]
class MyClass<T> : IService<T> { }
// 或者
[AddService(ServiceLifetime.Scoped, ServiceType = typeof(IService<string>))]
class MyClass<T> : IService<T> { }

生成代码

var serviceType = typeof(Project1I.IService<string>);
var implementType = typeof(Project1.MyClass<string>);
service.AddScoped(serviceType, implementType);
  • 注册顺序

值越大越靠后

namespace Project1;

[AddService<IService>(ServiceLifetime.Singleton, Index = 9527)]
[AddService<IService>(ServiceLifetime.Transient)]
[AddService<IService>(ServiceLifetime.Scoped)]
internal class MyClass : IService{ }

生成代码如下


service.AddTransient(typeof(Project1.MyClass));
service.AddScoped(typeof(Project1.MyClass));
// 根据 Index 下移
service.AddSingleton(typeof(Project1.MyClass));
  • 指定构造函数

特性标记在类上时使用主构函数,否则根据标记的函数生成。

namespace Project1;
class MyClass
{
    public MyClass() { }

    [AddService(ServiceLifetime.Scoped)]
    public MyClass(string msg) => Message = msg;

    public string Message { get; }
}

生成代码

var serviceType = typeof(Project1.MyClass);
static object implement(IServiceProvider s) => new Project1.MyClass
(
    s.GetRequiredService<string>()
);
service.AddScoped(serviceType, implement);
  • 指定工厂

namespace Project1;

[AddService(ServiceLifetime.Singleton, Factory = nameof(Factory))]
internal class MyClass 
{
    public static object Factory(IServiceProvider service) => new MyClass();
}

生成代码

var serviceType = typeof(Project1.MyClass);
service.AddSingleton(serviceType, Project1.MyClass.Factory);
  • Keyed

namespace Project1;

[AddService(ServiceLifetime.Singleton, Keyed = "key")]
class MyClass { }

生成代码

object? keyed = "key";
service.AddKeyedSingleton(typeof(Project1.MyClass), keyed);
  • TryAdd

namespace Project1;

[AddService(ServiceLifetime.Scoped, TryAdd = true)]
class MyClass { }

生成代码

service.TryAddScoped(typeof(Project1.MyClass));

AddOptions

namespace Project1;

[AddOptions]
class MyOptions
{ }

 // 泛型类
[AddOptions<MyOptions<string>>]
class MyOptions<T> 
{ }

 // 泛型类 typeof
[AddOptions(Type = typeof(MyOptions<string>))]
 class MyOptions<T> 
{ }

生成代码如下

namespace Project1;

public static partial class ShadowCodeInjectionExtensions
{
    // g_configure 由生成器调用!
    static partial void g_configure(IServiceCollection service, IConfigurationManager config)
    {
        service.Configure<MyOptions>(config);
        service.Configure<MyOptions<string>>(config);
    }
}
  • 指定Section 或 Name

namespace Project1;
[AddOptions<MyOptions<string>>("sectionKey", Name = "nameValue")]
class MyOptions<T> 
{ }

// 或 typeof(MyOptions<string>)
[AddOptions("sectionKey", Name = "nameValue", Type = typeof(MyOptions<string>))]
class MyOptions<T> 
{ }

生成代码如下

namespace Project1;
public static partial class ShadowCodeInjectionExtensions
{
    // g_configure 由生成器调用!
    static partial void g_configure(IServiceCollection service, IConfigurationManager config)
    {
        service.Configure<MyOptions<string>>("nameValue", config.GetSection("sectionKey"));
    }
}
  • 命令行

ConfigurationManager configurationManager = new();
ServiceCollection serviceCollection = new();

configurationManager.AddJsonFile("JsonPath", true, true);
serviceCollection.AddSingleton<IConfiguration>(configurationManager);

ServiceProvider service = serviceCollection
    .Use项目名称(configurationManager)
    .BuildServiceProvider();

var v = service.GetRequiredService<IOptionsSnapshot<XXX>>().Value;
var v = service.GetRequiredService<IOptionsSnapshot<XXX>>().Get("name").Value;
There are no supported framework assets in this package.

Learn more about Target Frameworks and .NET Standard.

  • .NETStandard 2.0

    • No dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
2.0.4 78 5/3/2025
2.0.3 147 4/28/2025
2.0.2 173 4/28/2025
2.0.1 98 4/19/2025
2.0.0 107 12/11/2024