public OperationsFactory([CanBeNull] string startupProject, [CanBeNull] string environment)
        {
            var project = Directory.GetCurrentDirectory();

            startupProject = startupProject ?? project;

            var startupProjectContext = ProjectContext.CreateContextForEachFramework(startupProject).First();
            var projectContext        = ProjectContext.CreateContextForEachFramework(project).First();
            var startupAssemblyName   = new AssemblyName(startupProjectContext.ProjectFile.Name);
            var assemblyName          = new AssemblyName(projectContext.ProjectFile.Name);
            var assemblyLoadContext   = startupProjectContext.CreateLoadContext();

            _startupAssembly = assemblyLoadContext.LoadFromAssemblyName(startupAssemblyName);

            try
            {
                _assembly = assemblyLoadContext.LoadFromAssemblyName(assemblyName);
            }
            catch (Exception ex)
            {
                throw new OperationException(
                          CommandsStrings.UnreferencedAssembly(
                              projectContext.ProjectFile.Name,
                              startupProjectContext.ProjectFile.Name),
                          ex);
            }
            _environment   = environment;
            _projectDir    = projectContext.ProjectDirectory;
            _rootNamespace = projectContext.ProjectFile.Name;
        }
        public OperationExecutor([NotNull] object logHandler, [NotNull] IDictionary args)
        {
            Check.NotNull(logHandler, nameof(logHandler));
            Check.NotNull(args, nameof(args));

            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"];
            var projectDir        = (string)args["projectDir"];
            var rootNamespace     = (string)args["rootNamespace"];

            var startupAssembly = Assembly.Load(new AssemblyName(startupTargetName));

            Assembly assembly;

            try
            {
                assembly = Assembly.Load(new AssemblyName(targetName));
            }
            catch (Exception ex)
            {
                throw new OperationException(CommandsStrings.UnreferencedAssembly(targetName, startupTargetName), ex);
            }

            _contextOperations = new LazyRef <DbContextOperations>(
                () => new DbContextOperations(
                    loggerProvider,
                    assembly,
                    startupAssembly,
                    projectDir, environment));
            _databaseOperations = new LazyRef <DatabaseOperations>(
                () => new DatabaseOperations(
                    loggerProvider,
                    assembly,
                    startupAssembly,
                    environment,
                    projectDir,
                    rootNamespace));
            _migrationsOperations = new LazyRef <MigrationsOperations>(
                () => new MigrationsOperations(
                    loggerProvider,
                    assembly,
                    startupAssembly,
                    environment,
                    projectDir,
                    rootNamespace));
        }
        private Assembly GetAssembly()
        {
            if (_assembly == null)
            {
                try
                {
                    _assembly = Assembly.Load(new AssemblyName(_assemblyName));
                }
                catch (Exception ex)
                {
                    throw new OperationException(CommandsStrings.UnreferencedAssembly(_assemblyName, _startupAssemblyName), ex);
                }
            }

            return(_assembly);
        }
Example #4
0
        private IDictionary <Type, Func <DbContext> > FindContextTypes()
        {
            _logger.Value.LogDebug(CommandsStrings.LogFindingContexts);

            var startupAssembly = Assembly.Load(new AssemblyName(_startupAssemblyName));
            var contexts        = new Dictionary <Type, Func <DbContext> >();

            // Look for IDbContextFactory implementations
            var contextFactories = startupAssembly.GetConstructibleTypes()
                                   .Where(t => typeof(IDbContextFactory <DbContext>).GetTypeInfo().IsAssignableFrom(t));

            foreach (var factory in contextFactories)
            {
                var manufacturedContexts =
                    from i in factory.ImplementedInterfaces
                    where i.GetTypeInfo().IsGenericType &&
                    i.GetGenericTypeDefinition() == typeof(IDbContextFactory <>)
                    select i.GenericTypeArguments[0];
                foreach (var context in manufacturedContexts)
                {
                    contexts.Add(
                        context,
                        () => ((IDbContextFactory <DbContext>)Activator.CreateInstance(factory.AsType())).Create());
                }
            }

            // Look for DbContext classes registered in the service provider
            var registeredContexts = _runtimeServices.GetServices <DbContextOptions>()
                                     .Select(o => o.GetType().GenericTypeArguments[0]);

            foreach (var context in registeredContexts.Where(c => !contexts.ContainsKey(c)))
            {
                contexts.Add(
                    context,
                    FindContextFactory(context) ?? (() => (DbContext)_runtimeServices.GetRequiredService(context)));
            }

            // Look for DbContext classes in assemblies
            Assembly assembly;

            try
            {
                assembly = Assembly.Load(new AssemblyName(_assemblyName));
            }
            catch (Exception ex)
            {
                throw new OperationException(CommandsStrings.UnreferencedAssembly(_assemblyName, _startupAssemblyName), ex);
            }

            var types = startupAssembly.GetConstructibleTypes()
                        .Concat(assembly.GetConstructibleTypes())
                        .Select(i => i.AsType());
            var contextTypes = types.Where(t => typeof(DbContext).IsAssignableFrom(t))
                               .Concat(
                types.Where(t => typeof(Migration).IsAssignableFrom(t))
                .Select(t => t.GetTypeInfo().GetCustomAttribute <DbContextAttribute>()?.ContextType)
                .Where(t => t != null))
                               .Distinct();

            foreach (var context in contextTypes.Where(c => !contexts.ContainsKey(c)))
            {
                contexts.Add(
                    context,
                    FindContextFactory(context) ?? (() => (DbContext)Activator.CreateInstance(context)));
            }

            return(contexts);
        }