解决MySql布尔型新旧版本兼容问题,采用枚举来表示布尔型的数据表。由正向工程赋值
|
# 对象容器 ObjectContainer
## 简介
`ObjectContainer` 是 NewLife.Core ä¸çš„è½»é‡çº§å¯¹è±¡å®¹å™¨ï¼Œæ”¯æŒä¾èµ–注入(DI)功能。æä¾›ç®€å•而强大的 IoC 容器功能,支æŒå•例ã€çž¬æ€å’Œä½œç”¨åŸŸç”Ÿå‘½å‘¨æœŸï¼Œå…¼å®¹ `IServiceProvider` 接å£ï¼Œå¯ä»¥ä½œä¸º ASP.NET Core 内置 DI 的补充或替代。
**命å空间**:`NewLife.Model`
**文档地å€**:https://newlifex.com/core/object_container
## æ ¸å¿ƒç‰¹æ€§
- **è½»é‡çº§**ï¼šæ— å¤–éƒ¨ä¾èµ–,代ç 精简
- **三ç§ç”Ÿå‘½å‘¨æœŸ**:å•例(Singleton)ã€çž¬æ€ï¼ˆTransient)ã€ä½œç”¨åŸŸï¼ˆScoped)
- **æž„é€ å‡½æ•°æ³¨å…¥**ï¼šè‡ªåŠ¨è§£æžæž„é€ å‡½æ•°å‚æ•°ï¼Œä¼˜å…ˆé€‰æ‹©å‚数最多的å¯åŒ¹é…æž„é€ å‡½æ•°
- **工厂委托**:支æŒè‡ªå®šä¹‰å®žä¾‹åˆ›å»ºé€»è¾‘
- **全局容器**:æä¾› `ObjectContainer.Current` å’Œ `ObjectContainer.Provider` 全局访问
- **æ ‡å‡†å…¼å®¹**:实现 `IServiceProvider` 接å£ï¼Œä¸Žæ ‡å‡† DI 容器互æ“作
- **作用域支æŒ**ï¼šæ”¯æŒ `IServiceScope` å’Œ `IServiceScopeFactory`
## 快速开始
```csharp
using NewLife.Model;
// 获å–全局容器
var ioc = ObjectContainer.Current;
// 注册æœåŠ¡
ioc.AddSingleton<ILogger, ConsoleLogger>(); // å•例
ioc.AddTransient<IUserService, UserService>(); // 瞬æ€
ioc.AddScoped<IDbContext, MyDbContext>(); // 作用域
// 构建æœåŠ¡æä¾›è€…
var provider = ioc.BuildServiceProvider();
// è§£æžæœåŠ¡
var logger = provider.GetService<ILogger>();
var userService = provider.GetRequiredService<IUserService>();
```
## æ ¸å¿ƒç±»åž‹
### IObjectContainer 接å£
å¯¹è±¡å®¹å™¨çš„æ ¸å¿ƒæŽ¥å£ï¼Œå®šä¹‰äº†æœåŠ¡æ³¨å†Œå’Œè§£æžçš„基本能力。
| æˆå‘˜ | 类型 | 说明 |
|------|------|------|
| `Services` | `IList<IObject>` | æœåŠ¡æ³¨å†Œé›†åˆ |
| `Register` | 方法 | 注册类型和åç§°ï¼ˆå·²æ ‡è®° EditorBrowsable.Never) |
| `Add` | 方法 | æ·»åŠ æœåŠ¡æ³¨å†Œï¼Œå…许é‡å¤æ·»åŠ åŒä¸€ä¸ªæœåŠ¡ |
| `TryAdd` | 方法 | å°è¯•æ·»åŠ æœåŠ¡æ³¨å†Œï¼Œä¸å…许é‡å¤æ·»åŠ åŒä¸€ä¸ªæœåŠ¡ |
| `GetService` | 方法 | è§£æžç±»åž‹çš„实例 |
### ObjectLifetime 枚举
定义æœåŠ¡çš„ç”Ÿå‘½å‘¨æœŸç–略。
| 值 | 说明 |
|------|------|
| `Singleton` | å•实例,整个应用程åºç”Ÿå‘½å‘¨æœŸå†…åªæœ‰ä¸€ä¸ªå®žä¾‹ |
| `Scoped` | 容器内å•实例,åŒä¸€ä½œç”¨åŸŸå†…共享实例 |
| `Transient` | æ¯æ¬¡ä¸€ä¸ªå®žä¾‹ï¼Œæ¯æ¬¡è¯·æ±‚都创建新实例 |
### IObject 接å£
å¯¹è±¡æ˜ å°„æŽ¥å£ï¼Œæè¿°æœåŠ¡çš„ç±»åž‹ã€å®žçŽ°å’Œç”Ÿå‘½å‘¨æœŸã€‚
| æˆå‘˜ | 类型 | 说明 |
|------|------|------|
| `ServiceType` | `Type` | æœåŠ¡ç±»åž‹ï¼ŒæŽ¥å£æˆ–抽象类类型 |
| `ImplementationType` | `Type?` | 实现类型,具体实现类类型 |
| `Lifetime` | `ObjectLifetime` | 生命周期,控制实例的创建和销æ¯ç–ç•¥ |
### ServiceDescriptor ç±»
æœåŠ¡æè¿°ç¬¦ï¼Œå®žçް `IObject` 接å£ï¼Œæè¿°æœåŠ¡çš„å®Œæ•´ä¿¡æ¯ã€‚
| 属性 | 类型 | 说明 |
|------|------|------|
| `ServiceType` | `Type` | æœåŠ¡ç±»åž‹ï¼Œé€šå¸¸æ˜¯æŽ¥å£æˆ–抽象类 |
| `ImplementationType` | `Type?` | 实现类型,具体的实现类 |
| `Lifetime` | `ObjectLifetime` | 生命周期 |
| `Instance` | `Object?` | æœåŠ¡å®žä¾‹ï¼Œä»…å•ä¾‹æ¨¡å¼æœ‰æ•ˆ |
| `Factory` | `Func<IServiceProvider, Object>?` | 对象工厂,用于创建æœåŠ¡å®žä¾‹çš„å§”æ‰˜ |
## API å‚考
### 全局访问
#### Current
```csharp
public static IObjectContainer Current { get; set; }
```
全局默认容器实例,应用å¯åŠ¨æ—¶è‡ªåŠ¨åˆ›å»ºã€‚
**示例**:
```csharp
// 在任何地方访问全局容器
var container = ObjectContainer.Current;
container.AddSingleton<IMyService, MyService>();
```
#### Provider
```csharp
public static IServiceProvider Provider { get; set; }
```
全局默认æœåŠ¡æä¾›è€…,由 `Current` 容器自动构建。
**示例**:
```csharp
// 直接通过全局æä¾›è€…è§£æžæœåŠ¡
var service = ObjectContainer.Provider.GetService<IMyService>();
```
#### SetInnerProvider
```csharp
// 设置内部æœåŠ¡æä¾›è€…(用于 UseXxx 阶段)
public static void SetInnerProvider(IServiceProvider innerServiceProvider)
// 设置内部æœåŠ¡æä¾›è€…工厂(用于 AddXxx 阶段延迟绑定)
public static void SetInnerProvider(Func<IServiceProvider> innerServiceProviderFactory)
```
用于与 ASP.NET Core ç‰æ¡†æž¶çš„ DI 容器集æˆï¼Œå®žçް链弿Ÿ¥æ‰¾ã€‚当 ObjectContainer 䏿‰¾ä¸åˆ°æœåŠ¡æ—¶ï¼Œä¼šè‡ªåŠ¨ä»Žå†…éƒ¨æä¾›è€…䏿Ÿ¥æ‰¾ã€‚
**示例**:
```csharp
// 在 Startup.Configure ä¸è®¾ç½®
public void Configure(IApplicationBuilder app)
{
ObjectContainer.SetInnerProvider(app.ApplicationServices);
}
// 或在 Program.cs ä¸ä½¿ç”¨å·¥åŽ‚å»¶è¿Ÿç»‘å®š
ObjectContainer.SetInnerProvider(() => app.Services);
```
### æœåŠ¡æ³¨å†Œ
#### AddSingleton(å•例)
```csharp
// æ³¨å†Œç±»åž‹æ˜ å°„
IObjectContainer AddSingleton<TService, TImplementation>()
IObjectContainer AddSingleton(Type serviceType, Type implementationType)
// 注册实例
IObjectContainer AddSingleton<TService>(TService? instance = null)
IObjectContainer AddSingleton(Type serviceType, Object? instance)
// 注册工厂
IObjectContainer AddSingleton<TService>(Func<IServiceProvider, TService> factory)
IObjectContainer AddSingleton(Type serviceType, Func<IServiceProvider, Object> factory)
```
注册å•例æœåŠ¡ï¼Œæ•´ä¸ªåº”ç”¨ç¨‹åºç”Ÿå‘½å‘¨æœŸåªæœ‰ä¸€ä¸ªå®žä¾‹ã€‚
**示例**:
```csharp
var ioc = ObjectContainer.Current;
// ç±»åž‹æ˜ å°„
ioc.AddSingleton<ILogger, FileLogger>();
// 直接注册实例
var config = new AppConfig { Debug = true };
ioc.AddSingleton<AppConfig>(config);
// 工厂委托(延迟创建)
ioc.AddSingleton<IDbConnection>(sp =>
{
var config = sp.GetService<AppConfig>();
return new SqlConnection(config.ConnectionString);
});
// æ³¨å†Œè‡ªèº«ç±»åž‹ï¼ˆæ— éœ€ä¼ å…¥å®žä¾‹ï¼Œå†…éƒ¨è‡ªåŠ¨å®žä¾‹åŒ–ï¼‰
ioc.AddSingleton<MyService>();
```
#### AddTransient(瞬æ€ï¼‰
```csharp
IObjectContainer AddTransient<TService, TImplementation>()
IObjectContainer AddTransient<TService>()
IObjectContainer AddTransient(Type serviceType, Type implementationType)
IObjectContainer AddTransient(Type serviceType, Func<IServiceProvider, Object> factory)
```
æ³¨å†Œçž¬æ€æœåŠ¡ï¼Œæ¯æ¬¡è¯·æ±‚都创建新实例。
**示例**:
```csharp
// æ¯æ¬¡è§£æžéƒ½åˆ›å»ºæ–°å®žä¾‹
ioc.AddTransient<IUserService, UserService>();
// 自身注册
ioc.AddTransient<OrderProcessor>();
// 工厂委托
ioc.AddTransient<HttpClient>(sp => new HttpClient
{
BaseAddress = new Uri("https://api.example.com"),
Timeout = TimeSpan.FromSeconds(30)
});
```
#### AddScoped(作用域)
```csharp
IObjectContainer AddScoped<TService, TImplementation>()
IObjectContainer AddScoped<TService>()
IObjectContainer AddScoped(Type serviceType, Type implementationType)
IObjectContainer AddScoped(Type serviceType, Func<IServiceProvider, Object> factory)
```
注册作用域æœåŠ¡ï¼ŒåŒä¸€ä½œç”¨åŸŸå†…共享实例。
**示例**:
```csharp
// åŒä¸€ä½œç”¨åŸŸå…±äº«
ioc.AddScoped<IDbContext, AppDbContext>();
// 工厂委托
ioc.AddScoped<IUnitOfWork>(sp =>
{
var context = sp.GetService<IDbContext>();
return new UnitOfWork(context);
});
```
#### TryAdd 系列
```csharp
// å•例
IObjectContainer TryAddSingleton<TService, TImplementation>()
IObjectContainer TryAddSingleton<TService>(TService? instance = null)
// 作用域
IObjectContainer TryAddScoped<TService, TImplementation>()
IObjectContainer TryAddScoped<TService>(TService? instance = null)
// 瞬æ€
IObjectContainer TryAddTransient<TService, TImplementation>()
IObjectContainer TryAddTransient<TService>(TService? instance = null)
```
å°è¯•æ·»åŠ æœåŠ¡ï¼Œå¦‚æžœå·²å˜åœ¨ç›¸åŒæœåŠ¡ç±»åž‹åˆ™ä¸æ·»åŠ ï¼Œè¿”å›ž `false`。
**示例**:
```csharp
// 仅在未注册时添åŠ
ioc.TryAddSingleton<ILogger, ConsoleLogger>();
// ç¬¬äºŒæ¬¡æ·»åŠ ä¸ä¼šç”Ÿæ•ˆ
ioc.TryAddSingleton<ILogger, FileLogger>(); // 被忽略
// 用 Add åˆ™ä¼šæ·»åŠ ï¼ˆæœ€åŽæ³¨å†Œçš„优先)
ioc.AddSingleton<ILogger, FileLogger>(); // 会添åŠ
```
### æœåŠ¡æž„å»º
#### BuildServiceProvider
```csharp
public static IServiceProvider BuildServiceProvider(this IObjectContainer container)
public static IServiceProvider BuildServiceProvider(this IObjectContainer container, IServiceProvider? innerServiceProvider)
```
从对象容器创建æœåŠ¡æä¾›è€…。
**示例**:
```csharp
var ioc = ObjectContainer.Current;
ioc.AddSingleton<IMyService, MyService>();
// 基本构建
var provider = ioc.BuildServiceProvider();
// 带内部æä¾›è€…ï¼ˆé“¾å¼æŸ¥æ‰¾ï¼‰
var provider2 = ioc.BuildServiceProvider(existingProvider);
```
#### BuildHost
```csharp
public static IHost BuildHost(this IObjectContainer container)
public static IHost BuildHost(this IObjectContainer container, IServiceProvider? innerServiceProvider)
```
从对象容器创建应用主机。
**示例**:
```csharp
var ioc = ObjectContainer.Current;
ioc.AddSingleton<IMyService, MyService>();
var host = ioc.BuildHost();
host.Run();
```
### æœåŠ¡è§£æž
#### GetService(基本解æžï¼‰
```csharp
// IServiceProvider æŽ¥å£æ–¹æ³•
Object? GetService(Type serviceType)
// 泛型扩展方法
T? GetService<T>(this IServiceProvider provider)
T? GetService<T>(this IObjectContainer container)
```
èŽ·å–æœåŠ¡å®žä¾‹ï¼Œæœªæ‰¾åˆ°æ—¶è¿”å›ž nullã€‚è§£æžæ—¶ä¼˜å…ˆæŸ¥æ‰¾æœ€åŽæ³¨å†Œçš„æœåŠ¡ã€‚
**示例**:
```csharp
var service = provider.GetService(typeof(IMyService));
var typedService = provider.GetService<IMyService>();
// 直接从容器获å–
var containerService = ioc.GetService<IMyService>();
```
#### GetRequiredService(必è¦è§£æžï¼‰
```csharp
Object GetRequiredService(this IServiceProvider provider, Type serviceType)
T GetRequiredService<T>(this IServiceProvider provider)
```
获å–å¿…è¦çš„æœåŠ¡ï¼Œæœªæ‰¾åˆ°æ—¶æŠ›å‡º `InvalidOperationException` 异常。
**示例**:
```csharp
// 如果未注册会抛出异常
var config = provider.GetRequiredService<AppConfig>();
```
#### GetServices(批é‡è§£æžï¼‰
```csharp
IEnumerable<Object> GetServices(this IServiceProvider provider, Type serviceType)
IEnumerable<T> GetServices<T>(this IServiceProvider provider)
```
èŽ·å–æŒ‡å®šç±»åž‹çš„æ‰€æœ‰æœåŠ¡å®žä¾‹ï¼ˆæ”¯æŒåŒä¸€æœåŠ¡ç±»åž‹çš„å¤šä¸ªæ³¨å†Œï¼‰ã€‚è¿”å›žé¡ºåºä¸ºæ³¨å†Œçš„逆åºï¼ˆæœ€åŽæ³¨å†Œçš„æœ€å…ˆè¿”回)。
**示例**:
```csharp
// 注册多个处ç†å™¨
ioc.AddSingleton<IMessageHandler, EmailHandler>();
ioc.AddSingleton<IMessageHandler, SmsHandler>();
ioc.AddSingleton<IMessageHandler, PushHandler>();
// èŽ·å–æ‰€æœ‰å¤„ç†å™¨
var handlers = provider.GetServices<IMessageHandler>();
foreach (var handler in handlers)
{
handler.Handle(message);
}
```
### 作用域支æŒ
#### IServiceScope 接å£
范围æœåŠ¡æŽ¥å£ï¼Œè¯¥èŒƒå›´ç”Ÿå‘½å‘¨æœŸå†…,æ¯ä¸ªæœåŠ¡ç±»åž‹åªæœ‰ä¸€ä¸ªå®žä¾‹ã€‚
```csharp
public interface IServiceScope : IDisposable
{
IServiceProvider ServiceProvider { get; }
}
```
#### IServiceScopeFactory 接å£
范围æœåŠ¡å·¥åŽ‚æŽ¥å£ã€‚
```csharp
public interface IServiceScopeFactory
{
IServiceScope CreateScope();
}
```
#### CreateScope
```csharp
IServiceScope? CreateScope(this IServiceProvider provider)
```
创建范围作用域,该作用域内 Scoped æœåŠ¡å…±äº«åŒä¸€å®žä¾‹ã€‚
**示例**:
```csharp
using var scope = provider.CreateScope();
var scopedService = scope.ServiceProvider.GetService<IDbContext>();
// scopedService 在æ¤ä½œç”¨åŸŸå†…是唯一的
// ä½œç”¨åŸŸå†…å†æ¬¡èŽ·å–,返回åŒä¸€å®žä¾‹
var scopedService2 = scope.ServiceProvider.GetService<IDbContext>();
// scopedService == scopedService2
```
#### CreateInstance
```csharp
Object? CreateInstance(this IServiceProvider provider, Type serviceType)
```
创建æœåŠ¡å¯¹è±¡ï¼Œä½¿ç”¨æœåŠ¡æä¾›è€…æ¥å¡«å……æž„é€ å‡½æ•°å‚æ•°ã€‚å¯ç”¨äºŽåˆ›å»ºæœªæ³¨å†Œç±»åž‹çš„实例。
**示例**:
```csharp
// 创建未注册类型的实例,自动注入已注册的ä¾èµ–
var instance = provider.CreateInstance(typeof(MyController));
```
## 生命周期详解
### Singleton(å•例)
```csharp
ioc.AddSingleton<IMyService, MyService>();
```
- **创建时机**:首次请求时创建
- **实例数é‡**:整个应用程åºåªæœ‰ä¸€ä¸ªå®žä¾‹
- **释放时机**:应用程åºç»“æŸæ—¶é‡Šæ”¾
- **适用场景**:é…ç½®ã€æ—¥å¿—ã€ç¼“å˜ç‰æ— çŠ¶æ€æˆ–全局共享的æœåŠ¡
- **注æ„事项**:å•例æœåŠ¡ä¸åº”ä¾èµ–作用域æœåŠ¡
### Transient(瞬æ€ï¼‰
```csharp
ioc.AddTransient<IMyService, MyService>();
```
- **创建时机**ï¼šæ¯æ¬¡è¯·æ±‚时创建
- **实例数é‡**ï¼šæ¯æ¬¡è¯·æ±‚都是新实例
- **释放时机**:使用完å³å¯è¢« GC 回收
- **适用场景**:轻é‡çº§ã€æ— 状æ€çš„æœåŠ¡
- **注æ„事项**:频ç¹åˆ›å»ºå¯èƒ½å½±å“性能
### Scoped(作用域)
```csharp
ioc.AddScoped<IMyService, MyService>();
```
- **创建时机**:作用域内首次请求时创建
- **实例数é‡**:æ¯ä¸ªä½œç”¨åŸŸä¸€ä¸ªå®žä¾‹
- **释放时机**ï¼šä½œç”¨åŸŸé”€æ¯æ—¶é‡Šæ”¾
- **适用场景**:Web è¯·æ±‚ã€æ•°æ®åº“上下文ç‰
- **注æ„事项**:需è¦é€šè¿‡ `CreateScope()` 创建作用域
## æž„é€ å‡½æ•°æ³¨å…¥
ObjectContainer 支æŒè‡ªåŠ¨æž„é€ å‡½æ•°æ³¨å…¥ï¼Œé€‰æ‹©å‚æ•°æœ€å¤šçš„å¯åŒ¹é…æž„é€ å‡½æ•°ï¼š
```csharp
public interface ILogger { void Log(String message); }
public class ConsoleLogger : ILogger
{
public void Log(String message) => Console.WriteLine(message);
}
public interface IRepository { }
public class UserRepository : IRepository
{
public ILogger Logger { get; }
// æž„é€ å‡½æ•°æ³¨å…¥
public UserRepository(ILogger logger)
{
Logger = logger;
}
}
public class UserService
{
public IRepository Repository { get; }
public ILogger Logger { get; }
// å¤šå‚æ•°æž„é€ å‡½æ•°
public UserService(IRepository repository, ILogger logger)
{
Repository = repository;
Logger = logger;
}
}
// 注册æœåŠ¡
var ioc = ObjectContainer.Current;
ioc.AddSingleton<ILogger, ConsoleLogger>();
ioc.AddSingleton<IRepository, UserRepository>();
ioc.AddSingleton<UserService>();
// è§£æžæ—¶è‡ªåŠ¨æ³¨å…¥ä¾èµ–
var provider = ioc.BuildServiceProvider();
var userService = provider.GetService<UserService>();
// userService.Logger 和 userService.Repository 都已自动注入
```
### æž„é€ å‡½æ•°é€‰æ‹©è§„åˆ™
1. 获å–ç±»åž‹çš„æ‰€æœ‰å…¬å…±å®žä¾‹æž„é€ å‡½æ•°
2. æŒ‰å‚æ•°æ•°é‡é™åºæŽ’列
3. 便¬¡å°è¯•匹é…ï¼Œé€‰æ‹©ç¬¬ä¸€ä¸ªæ‰€æœ‰å‚æ•°éƒ½èƒ½è§£æžçš„æž„é€ å‡½æ•°
4. åŸºæœ¬ç±»åž‹å‚æ•°ï¼ˆInt32ã€Stringã€Boolean ç‰ï¼‰ä½¿ç”¨é»˜è®¤å€¼
5. 如果没有å¯åŒ¹é…çš„æž„é€ å‡½æ•°ï¼ŒæŠ›å‡º `InvalidOperationException`
### 支æŒçš„é»˜è®¤å‚æ•°ç±»åž‹
| 类型 | 默认值 |
|------|--------|
| `Boolean` | `false` |
| `Char` | `(Char)0` |
| `SByte`/`Byte` | `0` |
| `Int16`/`UInt16` | `0` |
| `Int32`/`UInt32` | `0` |
| `Int64`/`UInt64` | `0` |
| `Single`/`Double` | `0` |
| `Decimal` | `0` |
| `DateTime` | `DateTime.MinValue` |
| `String` | `null` |
## 与 ASP.NET Core 集æˆ
### æ–¹å¼ä¸€ï¼šä½œä¸ºè¡¥å……容器
```csharp
// Program.cs
var builder = WebApplication.CreateBuilder(args);
// 使用 ASP.NET Core 的 DI
builder.Services.AddControllers();
builder.Services.AddScoped<IUserService, UserService>();
var app = builder.Build();
// 设置内部æä¾›è€…ï¼Œå®žçŽ°é“¾å¼æŸ¥æ‰¾
ObjectContainer.SetInnerProvider(app.Services);
// 现在 ObjectContainer.Provider å¯ä»¥è§£æž ASP.NET Core 注册的æœåŠ¡
var userService = ObjectContainer.Provider.GetService<IUserService>();
```
### æ–¹å¼äºŒï¼šå»¶è¿Ÿç»‘定
```csharp
// 在 AddXxx 阶段使用工厂延迟绑定
ObjectContainer.SetInnerProvider(() => app.Services);
```
### æ–¹å¼ä¸‰ï¼šæ··åˆä½¿ç”¨
```csharp
// 在 NewLife 容噍䏿³¨å†Œ
ObjectContainer.Current.AddSingleton<ICache, MemoryCache>();
// 在 ASP.NET Core ä¸ä¹Ÿå¯ä»¥è®¿é—®
builder.Services.AddSingleton(sp =>
ObjectContainer.Provider.GetService<ICache>()!);
```
## 实战示例
### 1. 控制å°åº”用
```csharp
public class Program
{
public static void Main()
{
var ioc = ObjectContainer.Current;
// 注册æœåŠ¡
ioc.AddSingleton<ILogger, ConsoleLogger>();
ioc.AddSingleton<IConfiguration, JsonConfiguration>();
ioc.AddTransient<IUserService, UserService>();
// 构建并è¿è¡Œ
var provider = ioc.BuildServiceProvider();
var service = provider.GetRequiredService<IUserService>();
service.Process();
}
}
```
### 2. Web 应用
```csharp
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
// å°† NewLife å®¹å™¨çš„æ³¨å†ŒåŒæ¥åˆ° ASP.NET Core
var ioc = ObjectContainer.Current;
ioc.AddSingleton<IMyService, MyService>();
// å¤åˆ¶åˆ° ASP.NET Core 容器
foreach (var item in ioc.Services)
{
// 转æ¢å¹¶æ·»åŠ åˆ° services
}
}
}
```
### 3. æ’件系统
```csharp
public class PluginLoader
{
private readonly IObjectContainer _container;
public PluginLoader()
{
_container = new ObjectContainer();
}
public void LoadPlugins(String pluginPath)
{
var assemblies = Directory.GetFiles(pluginPath, "*.dll")
.Select(Assembly.LoadFrom);
foreach (var assembly in assemblies)
{
var pluginTypes = assembly.GetTypes()
.Where(t => typeof(IPlugin).IsAssignableFrom(t) && !t.IsAbstract);
foreach (var type in pluginTypes)
{
_container.AddTransient(typeof(IPlugin), type);
}
}
}
public IEnumerable<IPlugin> GetPlugins()
{
var provider = _container.BuildServiceProvider();
return provider.GetServices<IPlugin>();
}
}
```
### 4. å•元测试
```csharp
[TestClass]
public class UserServiceTests
{
private IServiceProvider _provider;
[TestInitialize]
public void Setup()
{
var ioc = new ObjectContainer();
// 注册 Mock æœåŠ¡
ioc.AddSingleton<ILogger>(new MockLogger());
ioc.AddSingleton<IRepository>(new MockRepository());
ioc.AddTransient<IUserService, UserService>();
_provider = ioc.BuildServiceProvider();
}
[TestMethod]
public void TestCreateUser()
{
var service = _provider.GetRequiredService<IUserService>();
var result = service.CreateUser("test");
Assert.IsNotNull(result);
}
}
```
## 高级用法
### æœåŠ¡æ›¿æ¢
使用 `Add` 方法å¯ä»¥é‡å¤æ³¨å†ŒåŒä¸€æœåŠ¡ç±»åž‹ï¼Œè§£æžæ—¶è¿”å›žæœ€åŽæ³¨å†Œçš„:
```csharp
ioc.AddSingleton<ILogger, ConsoleLogger>();
ioc.AddSingleton<ILogger, FileLogger>(); // 替æ¢
var logger = provider.GetService<ILogger>(); // 返回 FileLogger
```
### æ¡ä»¶æ³¨å†Œ
使用 `TryAdd` 实现æ¡ä»¶æ³¨å†Œï¼š
```csharp
// ä»…åœ¨æœªæ³¨å†Œæ—¶æ·»åŠ é»˜è®¤å®žçŽ°
ioc.TryAddSingleton<ILogger, ConsoleLogger>();
// 用户å¯ä»¥åœ¨æ¤ä¹‹å‰æ³¨å†Œè‡ªå·±çš„实现
```
### 工厂模å¼
```csharp
ioc.AddSingleton<IConnectionFactory>(sp =>
{
var config = sp.GetRequiredService<IConfiguration>();
var connStr = config["Database:ConnectionString"];
return new SqlConnectionFactory(connStr);
});
```
### 装饰器模å¼
```csharp
// 注册基础实现
ioc.AddSingleton<ILogger, ConsoleLogger>();
// 注册装饰器
ioc.AddSingleton<ILogger>(sp =>
{
var services = sp.GetServices<ILogger>().ToList();
var inner = services.Count > 1 ? services[1] : services[0];
return new LoggingDecorator(inner);
});
```
## 最佳实践
### 推è
1. **ä¼˜å…ˆä½¿ç”¨æŽ¥å£æ³¨å†Œ**:便于测试和替æ¢å®žçް
2. **åˆç†é€‰æ‹©ç”Ÿå‘½å‘¨æœŸ**:å•ä¾‹ç”¨äºŽæ— çŠ¶æ€æœåŠ¡ï¼Œä½œç”¨åŸŸç”¨äºŽæœ‰çŠ¶æ€ä½†éœ€è¦å…±äº«çš„æœåŠ¡
3. **使用 TryAdd 防æ¢è¦†ç›–**:库代ç ä¸ä½¿ç”¨ TryAdd å…许用户自定义实现
4. **早期注册,延迟解æž**:在应用å¯åŠ¨æ—¶å®Œæˆæ‰€æœ‰æ³¨å†Œ
### é¿å…
1. **é¿å…æœåŠ¡å®šä½å™¨æ¨¡å¼**:ä¸è¦åœ¨ä¸šåС代ç ä¸ç›´æŽ¥è°ƒç”¨ `ObjectContainer.Provider`
2. **é¿å…å•例ä¾èµ–作用域**:å•例æœåŠ¡ä¸åº”ä¾èµ–作用域æœåŠ¡
3. **é¿å…循环ä¾èµ–**:A ä¾èµ– B,B ä¾èµ– A 会导致解æžå¤±è´¥
4. **é¿å…在çƒç‚¹è·¯å¾„注册**:æœåŠ¡æ³¨å†Œåº”åœ¨å¯åŠ¨æ—¶å®Œæˆ
### 生命周期选择建议
```csharp
// é…ç½®ã€æ—¥å¿— → å•例
ioc.AddSingleton<AppConfig>();
ioc.AddSingleton<ILogger, FileLogger>();
// æ•°æ®åº“上下文 → 作用域(Web)或瞬æ€ï¼ˆæŽ§åˆ¶å°ï¼‰
ioc.AddScoped<IDbContext, AppDbContext>(); // Web
ioc.AddTransient<IDbContext, AppDbContext>(); // 控制å°
// 业务æœåŠ¡å¯¹è±¡ → 瞬æ€
ioc.AddTransient<IValidator, UserValidator>();
```
## 常è§é—®é¢˜
### Q: è§£æžæœåŠ¡æ—¶æŠ›å‡º "No suitable constructor" 异常
**åŽŸå› **ï¼šæž„é€ å‡½æ•°çš„æŸä¸ªå‚数类型未注册。
**解决**:
```csharp
// 检查并注册所有ä¾èµ–
ioc.AddSingleton<IDependency, Dependency>();
```
### Q: Scoped æœåŠ¡åœ¨å•例䏿— 法æ£ç¡®å·¥ä½œ
**åŽŸå› **:å•例æœåŠ¡çš„ç”Ÿå‘½å‘¨æœŸæ¯”ä½œç”¨åŸŸé•¿ï¼Œä¼šæŒæœ‰è¿‡æœŸçš„作用域实例。
**解决**:
```csharp
// 改用工厂模å¼
ioc.AddSingleton<IServiceFactory>(sp =>
new ServiceFactory(() => sp.CreateScope()));
```
### Q: åŒä¸€æŽ¥å£æ³¨å†Œå¤šä¸ªå®žçŽ°ï¼Œåªèƒ½èŽ·å–一个
**åŽŸå› **:`GetService<T>()` åªè¿”å›žæœ€åŽæ³¨å†Œçš„实现。
**解决**:
```csharp
// 使用 GetServices èŽ·å–æ‰€æœ‰å®žçް
var services = provider.GetServices<IHandler>();
```
### Q: 如何与 ASP.NET Core DI å…±å˜
**解决**:使用 `SetInnerProvider` å»ºç«‹é“¾å¼æŸ¥æ‰¾ï¼š
```csharp
ObjectContainer.SetInnerProvider(app.Services);
```
## 与 Microsoft.Extensions.DependencyInjection 对比
| 特性 | ObjectContainer | MS DI |
|------|-----------------|-------|
| ä¾èµ–å¤§å° | æžå°ï¼ˆæ— ä¾èµ–) | 需è¦é¢å¤–包 |
| 生命周期 | æ”¯æŒ | æ”¯æŒ |
| æž„é€ å‡½æ•°æ³¨å…¥ | æ”¯æŒ | æ”¯æŒ |
| 属性注入 | 䏿”¯æŒ | 䏿”¯æŒ |
| 方法注入 | 䏿”¯æŒ | 䏿”¯æŒ |
| è£…é¥°å™¨æ¨¡å¼ | æ‰‹åŠ¨æ”¯æŒ | æ”¯æŒ |
| éªŒè¯ | æ— | æ”¯æŒ |
| 全局访问 | 内置 | 需è¦è‡ªè¡Œå®žçް |
## 相关链接
- [NewLife.Core 项目主页](https://github.com/NewLifeX/X)
- [在线文档](https://newlifex.com/core/object_container)
- [应用主机 IHost](/NewLife/X/Blob/dev/Doc/./应用主机Host.md)
|