public OperationExecutor([NotNull] object logHandler, [NotNull] IDictionary args, [NotNull] AssemblyLoader assemblyLoader)
        {
            Check.NotNull(logHandler, nameof(logHandler));
            Check.NotNull(args, nameof(args));
            Check.NotNull(assemblyLoader, nameof(assemblyLoader));

            var unwrappedLogHandler = ForwardingProxy.Unwrap <IOperationLogHandler>(logHandler);
            var loggerProvider      = new LoggerProvider(name => new CommandLoggerAdapter(name, unwrappedLogHandler));

            var targetName        = (string)args["targetName"];
            var startupTargetName = (string)args["startupTargetName"];
            var environment       = (string)args["environment"];

            _projectDir = (string)args["projectDir"];
            var contentRootPath = (string)args["contentRootPath"];
            var rootNamespace   = (string)args["rootNamespace"];

            // NOTE: LazyRef is used so any exceptions get passed to the resultHandler
            var startupAssembly = new LazyRef <Assembly>(
                () => assemblyLoader.Load(startupTargetName));
            var assembly = new LazyRef <Assembly>(
                () =>
            {
                try
                {
                    return(assemblyLoader.Load(targetName));
                }
                catch (Exception ex)
                {
                    throw new OperationException(
                        DesignCoreStrings.UnreferencedAssembly(targetName, startupTargetName),
                        ex);
                }
            });

            _contextOperations = new LazyRef <DbContextOperations>(
                () => new DbContextOperations(
                    loggerProvider,
                    assembly.Value,
                    startupAssembly.Value,
                    environment,
                    contentRootPath));
            _databaseOperations = new LazyRef <DatabaseOperations>(
                () => new DatabaseOperations(
                    loggerProvider,
                    assemblyLoader,
                    startupAssembly.Value,
                    environment,
                    _projectDir,
                    contentRootPath,
                    rootNamespace));
            _migrationsOperations = new LazyRef <MigrationsOperations>(
                () => new MigrationsOperations(
                    loggerProvider,
                    assembly.Value,
                    assemblyLoader,
                    startupAssembly.Value,
                    environment,
                    _projectDir,
                    contentRootPath,
                    rootNamespace));
        }