// OptimizeExpression will implement caching of the scopes of ScopedLifestyles which will optimize // performance in case multiple scoped registrations are used within a single delegate. Here's an // example of how the expression gets optimized: // Before: // Func<HomeController> factory = () => // { // return new HomeController( // reg1.GetInstance(), // Hits ThreadLocal, hits dictionary // new SomeQueryHandler(reg1.GetInstance()), // Hits ThreadLocal, hits dictionary // new SomeCommandHandler(reg2.GetInstance())); // Hits ThreadLocal, hits dictionary // }; // After: // Func<HomeController> factory = () => // { // var scope1 = new LazyScope(scopeFactory1, container); // var value1 = new LazyScopedRegistration<IRepository, RepositoryImpl>(reg1); // var value2 = new LazyScopedRegistration<IService, ServiceImpl>(reg2); // // return new HomeController( // value1.GetInstance(scope1.Value), // Hits ThreadLocal, hits dictionary // new SomeQueryHandler(value1.GetInstance(scope1.Value)), // new SomeCommandHandler(value2.GetInstance(scope1.Value))); // Hits dictionary // }; private static Expression OptimizeExpression(Container container, Expression expression, OptimizableLifestyleInfo[] lifestyleInfos) { var lifestyleAssigmentExpressions = ( from lifestyleInfo in lifestyleInfos let scopeFactory = lifestyleInfo.Lifestyle.CreateCurrentScopeProvider(container) let newExpression = CreateNewLazyScopeExpression(scopeFactory, container) select Expression.Assign(lifestyleInfo.Variable, newExpression)) .ToArray(); var registrationInfos = ( from lifestyleInfo in lifestyleInfos from registrationInfo in lifestyleInfo.Registrations select registrationInfo) .ToArray(); var registrationAssignmentExpressions = ( from registrationInfo in registrationInfos let newExpression = CreateNewLazyScopedRegistration(registrationInfo.Registration) select Expression.Assign(registrationInfo.Variable, newExpression)) .ToArray(); var optimizedExpression = ObjectGraphOptimizerExpressionVisitor.Optimize(expression, registrationInfos); return(Expression.Block( variables: lifestyleInfos.Select(l => l.Variable) .Concat(registrationInfos.Select(r => r.Variable)), expressions: lifestyleAssigmentExpressions .Concat(registrationAssignmentExpressions .Concat(new[] { optimizedExpression })))); }
public static Expression Optimize(Expression expression, OptimizableRegistrationInfo[] registrationsToOptimize) { var optimizer = new ObjectGraphOptimizerExpressionVisitor(registrationsToOptimize); return(optimizer.Visit(expression)); }