.NET Core依赖注入:通过工厂方法注册服务较慢?

时间:2019-04-29 15:04:55

标签: c# dependency-injection .net-core

我认为通过工厂方法进行服务注册会更快(调用GetRequiredService<T>时),因为我自己创建了对象。但是,实际上它要慢一些。

有人知道为什么吗?

使用工厂方法进行服务注册:

ServiceCollection services = new ServiceCollection();

services.AddTransient<IServiceXxx>(sp =>
    new ServiceXxx(new ServiceA(), new ServiceB())
);

正常注册:

ServiceCollection services = new ServiceCollection();

services.AddTransient<IServiceA, ServiceA>();
services.AddTransient<IServiceB, ServiceB>();
services.AddTransient<IServiceXxx, ServiceXxx>();

测试结果:

// sw1= 1619, sw2 (Factory)=1362
// sw1= 1191, sw2 (Factory)=1410
// sw1= 1020, sw2 (Factory)=1254
// sw1= 1024, sw2 (Factory)=1244
// sw1= 1039, sw2 (Factory)=1250
// sw1= 1024, sw2 (Factory)=1227
// sw1= 1037, sw2 (Factory)=1250
// sw1= 1023, sw2 (Factory)=1240
// sw1= 1009, sw2 (Factory)=1230
// sw1= 1042, sw2 (Factory)=1227

完整代码如下:

using System;
using System.Diagnostics;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace FrameworkTest
{
[TestClass]
public class UnitTest1 : TestBase
{
    [TestMethod]
    public void TestMethod1()
    {
        long loopCount = 10L * 1000 * 1000;

        for (int i = 0; i < 10; i++)
        {
            var svcProvider1 = BuildSp();
            var svcProvider2 = BuildSpWithFactory();

            long sw1 = GetExecutionTime(svcProvider1, loopCount);
            long sw2 = GetExecutionTime(svcProvider2, loopCount);

            Console.WriteLine($"sw1={sw1}, sw2 (Factory)={sw2}");
        }

        // sw1= 1619, sw2 (Factory)=1362
        // sw1= 1191, sw2 (Factory)=1410
        // sw1= 1020, sw2 (Factory)=1254
        // sw1= 1024, sw2 (Factory)=1244
        // sw1= 1039, sw2 (Factory)=1250
        // sw1= 1024, sw2 (Factory)=1227
        // sw1= 1037, sw2 (Factory)=1250
        // sw1= 1023, sw2 (Factory)=1240
        // sw1= 1009, sw2 (Factory)=1230
        // sw1= 1042, sw2 (Factory)=1227
    }

    public IServiceProvider BuildSp()
    {
        ServiceCollection services = new ServiceCollection();

        services.AddTransient<IServiceA, ServiceA>();
        services.AddTransient<IServiceB, ServiceB>();
        services.AddTransient<IServiceXxx, ServiceXxx>();

        var svcProvider = services.BuildServiceProvider();
        return svcProvider;
    }

    public IServiceProvider BuildSpWithFactory()
    {
        ServiceCollection services = new ServiceCollection();

        services.AddTransient<IServiceXxx>(sp =>
            new ServiceXxx(new ServiceA(), new ServiceB())
        );

        var svcProvider = services.BuildServiceProvider();
        return svcProvider;
    }

    public long GetExecutionTime(IServiceProvider sp, long loopCount)
    {
        Stopwatch sw = Stopwatch.StartNew();
        for (int i = 0; i < loopCount; i++)
        {
            var svcX = sp.GetRequiredService<IServiceXxx>();
        }
        sw.Stop();
        return sw.ElapsedMilliseconds;
    }




    public interface IServiceA { }
    public interface IServiceB { }

    public interface IServiceXxx { }

    public class ServiceA : IServiceA { }
    public class ServiceB : IServiceB { }

    public class ServiceXxx : IServiceXxx
    {
        public ServiceXxx(IServiceA a, IServiceB b)
        {

        }
    }
}

0 个答案:

没有答案
相关问题