C# 与直接数据访问相比,Unity容器的性能有很大的不同
我有一个包含大约30个项目的解决方案,其中大多数使用MicrosoftUnity作为容器 对于这个测试,我在不同的区域和不同的网络中使用远程Azure SQL数据库,所以我期望延迟响应,但它不会影响这个测试 让我们使用Unity计算数据访问时间,使用DbContext计算直接数据访问时间,以下是以毫秒为单位的平均计算: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
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);
}