如何在ASP.NET Core应用中实现与第三方IoC/DI框架的整合?
我们知道整个ASP.NET Core建立在以ServiceCollection/ServiceProvider为核心的DI框架上,它甚至提供了扩展点使我们可以与第三方DI框架进行整合。对此比较了解的读者朋友应该很清楚,针对第三方DI框架的整合可以通过在定义Startup类型的ConfigureServices方法返回一个ServiceProvider来实现。但是真的有这么简单吗? 一、ConfigureServices方法返回的ServiceProvider貌似没有用!?我们可以通过一个简单的实例来说明这个问题。我们先定义了如下这个一个MyServiceProvider,它实际上是对另一个ServiceProvider的封装。简单起见,我们利用一个字典来保存服务接口与实现类型的映射关系,这个关系可以通过调用Registe方法来注册。在提供服务实例的GetService方法中,如果提供的服务类型已经被注册,我们会创建并返回对应的实例对象,否则我们将利用封装的这个ServiceProvider来提供服务。为了确保服务实例能够被正常回收,如果服务类型实现了IDisposable接口,我们会将它添加到通过字段_disposables表示的集合中。当MyServiceProvider的Dispose方法被调用的时候,提供的这些服务实例的Dispose方法会被调用。 1: public class MyServiceProvider : IServiceProvider,IDisposable 2: {
3: private IServiceProvider _innerServiceProvider; 4: private Dictionary<Type,Type> _services; 5: private List<IDisposable> _disposables; 6:?
7: public MyServiceProvider(IServiceProvider innerServiceProvider) 8: {
9: _innerServiceProvider = innerServiceProvider;
10: this._services = new Dictionary<Type,Type>(); 11: _disposables = new List<IDisposable>(); 12: }
13:?
14:?
15: public MyServiceProvider Register<TFrom,TTo>() where TTo: TFrom,new() 16: {
17: _services[typeof(TFrom)] = typeof(TTo); 18: return this; 19: }
20:?
21: object GetService(Type serviceType) 22: {
23: Type implementation;
24: if (_services.TryGetValue(serviceType,1)">out implementation)) 25: {
26: object service = Activator.CreateInstance(implementation); 27: IDisposable disposbale = service as IDisposable; 28: if (null != disposbale) 29: {
30: _disposables.Add(disposbale);
31: }
32: return service; 33: }
34: return _innerServiceProvider.GetService(serviceType); 35: }
36:?
37: void Dispose() 38: {
39: (_innerServiceProvider as IDisposable)?.Dispose(); 40: foreach (var it in _disposables) 41: {
42: it.Dispose();
43: }
44: _disposables.Clear();
45: }
46: }
我们按照如下的方式在一个ASP.NET Core应用中使用MyServiceProvider。如下面的代码片断中,在注册的Starup类型中,我们让ConfigureServices方法返回一个MyServiceProvider对象。服务接口IFoobar和实现类型Foobar之间的映射注册在这个MyServiceProvider对象上。在处理请求的时候,我们利用当前HttpContext对象的RequestServices属性得到为请求处理提供服务的ServiceProvider,并试图利用它得到注册的IFoobar服务。 static void Main(string[] args)
5: new WebHostBuilder()
7: .UseStartup<Startup>() 9: .Run(); 11: } 13: class Startup
public IServiceProvider ConfigureServices(IServiceCollection services) 18: .Register<IFoobar,Foobar>(); 23: app.UseDeveloperExceptionPage() 25: } 27: interface IFoobar { }
internal class ServiceScope : IServiceScope
4:? 6: { 8: } 10: { 14: 15: {
17: } 19:? 21: { 23: 24:?
27: _innerServiceFactory = innerServiceFactory; 29: } 31: { 33: } public MyServiceProvider(IServiceProvider innerServiceProvider,1)"> 5: _innerServiceProvider = innerServiceProvider; 7: _disposables = 9:?
12: if (serviceType == typeof(IServiceScopeFactory)) 14: IServiceScopeFactory innerServiceScopeFactory = _innerServiceProvider.GetRequiredService<IServiceScopeFactory>(); 17: ... 19: ... 相关内容
推荐文章
站长推荐
热点阅读
|