diff --git a/src/Microsoft.AspNetCore.Mvc.Core/ApplicationParts/ApplicationPartFactory.cs b/src/Microsoft.AspNetCore.Mvc.Core/ApplicationParts/ApplicationPartFactory.cs
new file mode 100644
index 0000000000..88a93f9881
--- /dev/null
+++ b/src/Microsoft.AspNetCore.Mvc.Core/ApplicationParts/ApplicationPartFactory.cs
@@ -0,0 +1,31 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System.Collections.Generic;
+using System.Reflection;
+
+namespace Microsoft.AspNetCore.Mvc.ApplicationParts
+{
+ ///
+ /// Specifies a contract for synthesizing one or more instances
+ /// from an .
+ ///
+ /// By default, Mvc registers each application assembly that it discovers as an .
+ /// Assemblies can optionally specify an to configure parts for the assembly
+ /// by using .
+ ///
+ ///
+ public abstract class ApplicationPartFactory
+ {
+ public static readonly string DefaultContextName = "Default";
+
+ ///
+ /// Gets one or more instances for the specified .
+ ///
+ /// The .
+ ///
+ /// The context name. By default, value of this parameter is .
+ ///
+ public abstract IEnumerable GetApplicationParts(Assembly assembly, string context);
+ }
+}
diff --git a/src/Microsoft.AspNetCore.Mvc.Core/ApplicationParts/ProvideApplicationPartFactoryAttribute.cs b/src/Microsoft.AspNetCore.Mvc.Core/ApplicationParts/ProvideApplicationPartFactoryAttribute.cs
new file mode 100644
index 0000000000..18efd45c34
--- /dev/null
+++ b/src/Microsoft.AspNetCore.Mvc.Core/ApplicationParts/ProvideApplicationPartFactoryAttribute.cs
@@ -0,0 +1,21 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+
+namespace Microsoft.AspNetCore.Mvc.ApplicationParts
+{
+ ///
+ /// Provides a type.
+ ///
+ [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = false)]
+ public sealed class ProvideApplicationPartFactoryAttribute : Attribute
+ {
+ public ProvideApplicationPartFactoryAttribute(Type factoryType)
+ {
+ ApplicationPartFactoryType = factoryType ?? throw new ArgumentNullException(nameof(factoryType));
+ }
+
+ public Type ApplicationPartFactoryType { get; }
+ }
+}
diff --git a/src/Microsoft.AspNetCore.Mvc.Core/ApplicationParts/RelatedAssemblyAttribute.cs b/src/Microsoft.AspNetCore.Mvc.Core/ApplicationParts/RelatedAssemblyAttribute.cs
new file mode 100644
index 0000000000..344c39542f
--- /dev/null
+++ b/src/Microsoft.AspNetCore.Mvc.Core/ApplicationParts/RelatedAssemblyAttribute.cs
@@ -0,0 +1,22 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using Microsoft.AspNetCore.Mvc.Core;
+
+namespace Microsoft.AspNetCore.Mvc.ApplicationParts
+{
+ [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
+ public sealed class RelatedAssemblyAttribute : Attribute
+ {
+ public RelatedAssemblyAttribute(string name)
+ {
+ if (string.IsNullOrEmpty(name))
+ {
+ throw new ArgumentException(Resources.ArgumentCannotBeNullOrEmpty, nameof(name));
+ }
+ }
+
+ public string Name { get; }
+ }
+}
diff --git a/src/Microsoft.AspNetCore.Mvc.Razor/ApplicationParts/CompiledRazorAssemblyApplicationPartFactory.cs b/src/Microsoft.AspNetCore.Mvc.Razor/ApplicationParts/CompiledRazorAssemblyApplicationPartFactory.cs
new file mode 100644
index 0000000000..4da198233a
--- /dev/null
+++ b/src/Microsoft.AspNetCore.Mvc.Razor/ApplicationParts/CompiledRazorAssemblyApplicationPartFactory.cs
@@ -0,0 +1,28 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using System.Collections.Generic;
+using System.Reflection;
+
+namespace Microsoft.AspNetCore.Mvc.ApplicationParts
+{
+ ///
+ /// Configures an assembly as a .
+ ///
+ public class CompiledRazorAssemblyApplicationPartFactory : ApplicationPartFactory
+ {
+ ///
+ public override IEnumerable GetApplicationParts(
+ Assembly assembly,
+ string configuration)
+ {
+ if (assembly == null)
+ {
+ throw new ArgumentNullException(nameof(assembly));
+ }
+
+ yield return new CompiledRazorAssemblyPart(assembly);
+ }
+ }
+}
diff --git a/src/Microsoft.AspNetCore.Mvc.Razor/ApplicationParts/CompiledRazorAssemblyPart.cs b/src/Microsoft.AspNetCore.Mvc.Razor/ApplicationParts/CompiledRazorAssemblyPart.cs
new file mode 100644
index 0000000000..bed15f201f
--- /dev/null
+++ b/src/Microsoft.AspNetCore.Mvc.Razor/ApplicationParts/CompiledRazorAssemblyPart.cs
@@ -0,0 +1,20 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using System.Reflection;
+
+namespace Microsoft.AspNetCore.Mvc.ApplicationParts
+{
+ public class CompiledRazorAssemblyPart : ApplicationPart
+ {
+ public CompiledRazorAssemblyPart(Assembly assembly)
+ {
+ Assembly = assembly ?? throw new ArgumentNullException(nameof(assembly));
+ }
+
+ public Assembly Assembly { get; }
+
+ public override string Name => Assembly.GetName().Name;
+ }
+}