zoukankan      html  css  js  c++  java
  • asp.net core 依赖注入几种常见情况

    先读一篇注入入门 全面理解 ASP.NET Core 依赖注入, 学习一下基本使用


    然后学习一招, 不使用接口规范, 直接写功能类, 一般情况下可以用来做单例.

    image

    参考https://www.cnblogs.com/tcjiaan/p/8732848.html



    如何在StartUp中的ConfigureServices方法里直接调用刚刚添加好的注册?

    // redis注入
    services.AddSingleton<IRedisConnection>(k => { return new RedisConnection(6, Configuration["RedisConnectionString"]); });


    方式一.
    services.AddSingleton<IConnectionMultiplexer, ConnectionMultiplexer>(x =>
                 { return x.GetService<IRedisConnection>().ConnectionMultiplexer; });


    方式二           

    var sp = services.BuildServiceProvider();
    services.AddSingleton<StackExchange.Redis.IConnectionMultiplexer>((x) => { return sp.GetService<IRedisConnection>().ConnectionMultiplexer; });


    services.AddScoped<ICacheManager, RedisCacheManager>();

    如何在StartUp中的Configure方法里直接调用刚刚添加好的注册?

    var 接口实例 = app.ApplicationServices.GetRequiredService<接口>();


    当一个接口被多个不同的类来实现, 我们需要按需调用的时候

    比如有一个接口

    IFlyProvider{ Fly(); };

    俩个实现类

    FlyByPlaneProvider{};

    FlyByRocketProvider{};



    如何配置,  在public IServiceProvider ConfigureServices(IServiceCollection services)中如下操作

    1. 先用断子绝孙法直接注册两个实现类

    services.AddTransient<FlyByPlaneProvider>();
    services.AddTransient<FlyByRocketProvider>();


    2. 注册一个返回 Func<string,IFlyProvider>的项

    services.AddTransient<Func<string, IFlyProvider>>(serviceProvider => key =>
    {

         if (key == "plane")
              return serviceProvider.GetService<CreateWezhanResponseProvider>();
          else
               return serviceProvider.GetService<FlyByRocketProvider>();

    //用到了上面提到的 直接调用刚刚添加好的注册
    });


    3. 使用

    比如, 这里有一个旅游管理  ITravelManager接口, 里面有个方法, FLyToRoma(string key)

    那么我们需要在实现类中


    public class TravelManager: ITravelManager
         {

            private readonly Func<string, IFlyProvider> _providerAccessor;


            FLyToRoma(string key){

                  var provider=_providerAccessor(key);

                  provider.Fly();

                  …………………

           }



    在SingleTon的Serivce中, 如何获取其他的Service?

    这里, 我们有一个定时任务, 需要每隔N分钟, 去数据库里做一些事情, 于是我们希望使用HostedService+Timer完成这个任务.

    services.AddSingleton<Microsoft.Extensions.Hosting.IHostedService, MYHostedService>();
    services.AddScoped<IXService, XService>(); //


    在MYHostedService中, 我们不能使用构造函数来注入 IXService, 因为MyHostedService是单例的, 这样注入的IXService也是单例的. 访问数据库的话, 连接用完释放关闭就直接GG.

    所以, 不能使用构造函数注入.

    那么, 我们可以注入一个  IServiceProvider services , 这玩意就是我们上面马上获取实例的构造Provider. 这个可是单例的. 我们注入这个进来是不是就可以用它来生成我们的IXService呢?

    回报错

    System.InvalidOperationException: 'Cannot consume scoped service 'IXService' from singleton 'Microsoft.AspNetCore.Hosting.Internal.HostedServiceExecutor'.'

    正确方法

    The reason you're not allowed to do this is because MyHostedService has a singleton lifetime, which is a longer lifetime than scoped. The basic assumption here is that a service that is registered as scoped should not be kept alive indefinitely, this could easily happen if a singleton service keeps a reference to a scoped service.

    I think the solution you're looking for is to inject IServiceProvider into MyHostedService, use it to create a new scope and new XService instance whenever you need it.

    That is, replace

    _xService.Foo();

    with

    using(var scope = _serviceProvider.CreateScope()) {
        var xService = scope.ServiceProvider.GetService<IXService>();
        xService.Foo();
    }

    An alternative, of course, would be to simply register XService as a singleton, by just replacing the call to AddScoped with AddSingleton, but I would not recommend it.

    Edit: I must admit to not reading your link before posting my response. However, I still think this is the most elegant solution.

    摘自(https://stackoverflow.com/questions/52020799/net-core-dependency-injection-to-hosted-service/52020992#52020992)

  • 相关阅读:
    LeetCode Count of Range Sum
    LeetCode 158. Read N Characters Given Read4 II
    LeetCode 157. Read N Characters Given Read4
    LeetCode 317. Shortest Distance from All Buildings
    LeetCode Smallest Rectangle Enclosing Black Pixels
    LeetCode 315. Count of Smaller Numbers After Self
    LeetCode 332. Reconstruct Itinerary
    LeetCode 310. Minimum Height Trees
    LeetCode 163. Missing Ranges
    LeetCode Verify Preorder Serialization of a Binary Tree
  • 原文地址:https://www.cnblogs.com/jianjialin/p/9543851.html
Copyright © 2011-2022 走看看