// 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 }))));
        }
Exemplo n.º 2
0
            public static Expression Optimize(Expression expression,
                                              OptimizableRegistrationInfo[] registrationsToOptimize)
            {
                var optimizer = new ObjectGraphOptimizerExpressionVisitor(registrationsToOptimize);

                return(optimizer.Visit(expression));
            }