解决MySql布尔型新旧版本兼容问题,采用枚举来表示布尔型的数据表。由正向工程赋值
大石头 authored at 2018-05-15 21:21:05
19.13 KiB
X
# ¶ÔÏóÈÝÆ÷ 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" Òì³£ **Ô­Òò**£º¹¹Ô캯ÊýµÄij¸ö²ÎÊýÀàÐÍδע²á¡£ **½â¾ö**£º ```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/master/Doc/./Ó¦ÓÃÖ÷»úHost.md)