C# 是Func<;T>;构造函数中的参数是否会降低IoC解析速度?
我正在努力提高IoC容器的性能。我们使用的是Unity和SimpleInjector,我们有一个具有此构造函数的类:C# 是Func<;T>;构造函数中的参数是否会降低IoC解析速度?,c#,inversion-of-control,unity-container,simple-injector,C#,Inversion Of Control,Unity Container,Simple Injector,我正在努力提高IoC容器的性能。我们使用的是Unity和SimpleInjector,我们有一个具有此构造函数的类: public AuditFacade( IIocContainer container, Func<IAuditManager> auditManagerFactory, Func<ValidatorFactory> validatorCreatorFactory, IUserContext userContext,
public AuditFacade(
IIocContainer container,
Func<IAuditManager> auditManagerFactory,
Func<ValidatorFactory> validatorCreatorFactory,
IUserContext userContext,
Func<ITenantManager> tenantManagerFactory,
Func<IMonitoringComponent> monitoringComponentFactory)
: base(container, auditManagerFactory, GlobalContext.CurrentTenant,
validatorCreatorFactory, userContext, tenantManagerFactory)
{
_monitoringComponent = new Lazy<IMonitoringComponent>(monitoringComponentFactory);
}
public AuditTenantComponent(Func<IAuditTenantRepository> auditTenantRepository)
{
_auditTenantRepository = new Lazy<IAuditTenantRepository>(auditTenantRepository);
}
public-AuditFacade(
iIOC集装箱,
Func auditManagerFactory,
Func validatorCreatorFactory,
IUserContext用户上下文,
Func租户管理工厂,
功能监控组件(工厂)
:base(容器、auditManagerFactory、GlobalContext.CurrentTenant、,
validatorCreatorFactory、userContext、tenantManagerFactory)
{
_monitoringComponent=新延迟(monitoringComponentFactory);
}
我还有另一个具有此构造函数的类:
public AuditFacade(
IIocContainer container,
Func<IAuditManager> auditManagerFactory,
Func<ValidatorFactory> validatorCreatorFactory,
IUserContext userContext,
Func<ITenantManager> tenantManagerFactory,
Func<IMonitoringComponent> monitoringComponentFactory)
: base(container, auditManagerFactory, GlobalContext.CurrentTenant,
validatorCreatorFactory, userContext, tenantManagerFactory)
{
_monitoringComponent = new Lazy<IMonitoringComponent>(monitoringComponentFactory);
}
public AuditTenantComponent(Func<IAuditTenantRepository> auditTenantRepository)
{
_auditTenantRepository = new Lazy<IAuditTenantRepository>(auditTenantRepository);
}
public AuditTenantComponent(Func AuditTenantPository)
{
_AuditEnterpository=新的惰性(AuditEnterpository);
}
我看到第二个问题在1毫秒内得到解决,大多数情况下,而第一个问题平均需要50-60毫秒。我相信慢一点的原因是因为参数,它有更多的参数。但是我如何才能提高这个较慢的程序的性能呢?我们使用
Func
作为参数,这是事实吗?如果这是造成速度缓慢的原因,我可以改变什么?您所做的每件事都有与之相关的成本。通常,递归解析的构造函数参数越多,花费的时间就越长。但是你必须决定费用是可以的还是太高
在您的情况下,50毫秒是否会造成瓶颈?您是只创建一个实例,还是在一个紧密的循环中吐出它们?仅将1毫秒与50毫秒进行比较可能会导致您谴责速度较慢的一个,但是如果用户无法判断50毫秒已经过去,并且不会在应用程序的其他地方造成问题,那么如果您不知道需要它,为什么要运行环圈以加快速度呢?您可以连接到简单注入器的管道并添加配置文件,这允许您发现哪些类型创建速度较慢。以下是您可以使用的扩展方法:
public struct ProfileData{
公共只读表达式BuildingEventArgs信息;
公共只读时间间隔已过;
公共配置文件数据(ExpressionBuildingEventArgs信息,时间跨度){
this.Info=Info;
this.appead=已过;
}
}
静态void enableprofileing(容器、列表profileLog){
container.ExpressionBuilding+=(s,e)=>{
Func profilingWrapper=创建者=>{
var watch=Stopwatch.StartNew();
var instance=creator.Invoke();
Add(新的ProfileData(e,watch.appeased));
返回实例;
};
Func instanceCreator=
表达式.Lambda(e.Expression.Compile();
e、 Expression=Expression.Convert(
表达式.调用(
表达式.Constant(profilingWrapper),
表达式.常量(instanceCreator)),
e、 了解执行类型);
};
}
您可以按如下方式使用它:
container.Register<IMonitoringComponent>(() => new LazyMonitoringComponentProxy(
new Lazy<IMonitoringComponent>(container.GetInstance<CostlyMonitoringComp>));
var container=newcontainer();
//TODO:您的注册在这里。
//钩住探查器
列表档案日志=新列表(1000);
//注册后再打电话。
启用配置文件(容器、配置文件日志);
//触发验证以允许预编译所有内容。
container.Verify();
profileLog.Clear();
//解析类型:
container.GetInstance();
//按时间顺序显示解析时间。
var slowestFirst=profileLog.OrderByDescending(line=>line.appeased);
foreach(最慢的var行优先)
{
Console.WriteLine(string.Format(“{0}ms:{1}”),
line.Info.knownImplementType.Name,
行。已用。总毫秒);
}
请注意,显示的时间包括解决依赖关系所需的时间,但这可能会让您很容易知道是什么类型导致延迟
关于这里给出的代码,我想注意两件重要的事情:
因此,不要在您的生产环境中使用它。您当前的设计可能有很多需要改进的地方。这些改进可以分为五类,即:
AuditFacade
类)这仅仅暴露了服务所需的功能。或者,在交叉关注点的情况下,根本不注入该行为,而是使用扩展类的行为的交叉关注点来包装实现
在您的例子中,我认为复杂的情况显然正在发生,因为7个注入依赖项中有6个没有被实现使用,而是只传递给基类。换句话说,这6个依赖项是基类的实现细节,而实现仍然被迫知道它们。通过抽象(部分)在服务背后的基类中,您可以将AuditFacade
需要的依赖项数量减少到两个依赖项:Func
和新的抽象。该抽象背后的实现将有6个构造函数依赖项,但a