C# 依赖注入 创建自己的Scope

在依赖注入的时候有时候我们需要创建工厂类或者Func<>来创建需要的类,但是这样有时候不太方便,除了使用上面的方式外,我们还可以自己创建Scope。

(在.net 程序里面我们最经常需要 用到的一个新的 Ef core 的 DbContext.比如避免 DbContext的实体缓存问题 因为项目架构,还有时间成本。我们很难去改动旧的代码。 所以也只能靠创建 Scope的方式来解决它了)

代码如下

public class Worker
    {
        private readonly IMessageWriter _messageWriter;
        private readonly IServiceProvider _sp;

        public Worker(IMessageWriter messageWriter, IServiceProvider sp)
        {
            _messageWriter = messageWriter;
            _sp = sp;
        }

        public async Task ExecuteAsync()
        {
            _messageWriter.Write($"Worker running at: {DateTimeOffset.Now}");
            for (int i = 0; i < 10; i++)
            {
                //使用Scope来获取类
                using (var scope = _sp.CreateScope())
                {
                    var innerWorker = scope.ServiceProvider.GetService<InnerWorker>();
                }
            }
        }
    }

上面的这种写法,可以让我们旧代码可以继续使用,而不需要改造成Func<>或者工厂方法。 但是这种写法,会让我们写单元测试比较麻烦。 可以使用下面的这个方法来Mock.

写一个Scope的辅助Mock方法

public static Mock<IServiceProvider> GetProvider()
{
    var serviceProvider = new Mock<IServiceProvider>();

    var serviceScope = new Mock<IServiceScope>();
    serviceScope.Setup(x => x.ServiceProvider).Returns(serviceProvider.Object);

    var serviceScopeFactory = new Mock<IServiceScopeFactory>();
    serviceScopeFactory
        .Setup(x => x.CreateScope())
        .Returns(serviceScope.Object);

    serviceProvider
        .Setup(x => x.GetService(typeof(IServiceScopeFactory)))
        .Returns(serviceScopeFactory.Object);

    return serviceProvider;
}

//进行Mock
var serviceProvider = ServiceProviderHelper.GetProvider();
serviceProvider.Setup(it => it.GetService(typeof(IXXInteface))).Returns(customerService.Object);
最近更新的
...