C# 与直接数据访问相比,Unity容器的性能有很大的不同

C# 与直接数据访问相比,Unity容器的性能有很大的不同,c#,performance,dependency-injection,inversion-of-control,ioc-container,C#,Performance,Dependency Injection,Inversion Of Control,Ioc Container,我有一个包含大约30个项目的解决方案,其中大多数使用MicrosoftUnity作为容器 对于这个测试,我在不同的区域和不同的网络中使用远程Azure SQL数据库,所以我期望延迟响应,但它不会影响这个测试 让我们使用Unity计算数据访问时间,使用DbContext计算直接数据访问时间,以下是以毫秒为单位的平均计算: Unity Container 8749 5757 7225 7072 7256 8791 7016 7465 8449 10741 7852.1 (average) DbCo

我有一个包含大约30个项目的解决方案,其中大多数使用MicrosoftUnity作为容器

对于这个测试,我在不同的区域和不同的网络中使用远程Azure SQL数据库,所以我期望延迟响应,但它不会影响这个测试

让我们使用Unity计算数据访问时间,使用DbContext计算直接数据访问时间,以下是以毫秒为单位的平均计算:

Unity Container
8749
5757
7225
7072
7256
8791
7016
7465
8449
10741
7852.1 (average)

DbContext
3599
2239
2902
2378
1898
1682
1692
1522
2773
2054
2273.9 (average)
因此,使用unity容器访问数据需要7852.1(平均)毫秒,同时使用DbContext访问数据需要2273.9(平均)毫秒。这是一个很大的性能瓶颈,你不觉得吗

让我分享一些代码片段,这将展示我如何在项目中使用Unity

项目中的Unity配置如下所示:

public class UnityConfig
    {
        private static Lazy<IUnityContainer> container = new Lazy<IUnityContainer>(() =>
        {
            var container = new UnityContainer();
            RegisterTypes(container);
            return container;
        });

        public static IUnityContainer GetConfiguredContainer()
        {
            return container.Value;
        }

        public static void RegisterTypes(IUnityContainer container)
        {
            //// Repositories
            container.RegisterType<ICartRepository, CartRepository>();
            // .... total 50 repositories registrations ....

            //// Services
            container.RegisterType<ICartService, CartService>();
            // .... total 72 services registrations ....
        }
    }


public static class UnityWebActivator
{
    public static void Start()
    {
        var container = UnityConfig.GetConfiguredContainer();
        FilterProviders.Providers.Remove(FilterProviders.Providers.OfType<FilterAttributeFilterProvider>().First());
        FilterProviders.Providers.Add(new UnityFilterAttributeFilterProvider(container));
        DependencyResolver.SetResolver(new UnityDependencyResolver(container));

        // TODO: Uncomment if you want to use PerRequestLifetimeManager
        // Microsoft.Web.Infrastructure.DynamicModuleHelper.DynamicModuleUtility.RegisterModule(typeof(UnityPerRequestHttpModule));
    }

    public static void Shutdown()
    {
        var container = UnityConfig.GetConfiguredContainer();
        container.Dispose();
    }
}

这就是我们在应用程序中使用的全部内容。您是否看到可以更改哪些内容以提高性能?

原因是您比较的两种方式完全不同,而不是因为统一性。第一种方法是:

var item = cartService.Get("id", "org_id");
其实现方式如下:

return cartRepository.GetAll().Where(i => i.OrganizationId == orgid && i.Id == id).FirstOrDefault()
其中
GetAll
是:

public IEnumerable<Cart> GetAll()
{
    return db.Carts.AsNoTracking().Where(i => i.IsDeleted == 0);
}
这一个生成您期望的SQL,比如
从购物车中选择Top1*,其中IsDeleted=0,Id=@Id和OrganizationId=@org\u Id
,所有筛选都在数据库中进行,然后通过网络只传输一行

要修复-更改
GetAll
(和其他类似方法)以返回
IQueryable

public IQueryable<Cart> GetAll()
{
    return db.Carts.AsNoTracking().Where(i => i.IsDeleted == 0);
}
public IQueryable GetAll()
{
返回db.Carts.AsNoTracking(),其中(i=>i.IsDeleted==0);
}

您可以添加用于生成度量值的代码片段吗?我认为您没有提供“direct DbContext”方法的代码,因此我们不知道您在与什么进行比较。另外,
cartRepository.GetAll()
实现丢失。代码更新了您需要的所有详细信息从IEnumerable转换为IQueryable是一个不错的选择,谢谢您的帮助。
public IEnumerable<Cart> GetAll()
{
    return db.Carts.AsNoTracking().Where(i => i.IsDeleted == 0);
}
data.Carts.AsNoTracking().Where(i => i.Id == "id" && i.OrganizationId == "org_id").FirstOrDefault();
public IQueryable<Cart> GetAll()
{
    return db.Carts.AsNoTracking().Where(i => i.IsDeleted == 0);
}