Skip to content
This repository was archived by the owner on Dec 14, 2018. It is now read-only.
This repository was archived by the owner on Dec 14, 2018. It is now read-only.

MVC Assets from DI + Multiproject MVC Design Notes #4089

Closed
@danroth27

Description

@danroth27

Some design notes on this topic and a few related bugs.
#4087
#4014

Summary

We want to separate the configuration setting to use DI for creating controllers et al from specifying what assemblies and types to include as controllers. We're looking to support the scenarios users have been asking for with using MVC assets and views from multiple projects/assemblies.

DI

We're going to start by decoupling AddControllersAsServices() from specifying which assemblies should be considered "MVC" assemblies. There are lots of requests for more flexibility to register an "MVC" assembly at startup time, and that shouldn't be tied to the decision to use DI.

Additionally, we want to add support for AddViewComponentsAsServices() and AddTagHelpersAsServices().

All three of these methods (or something with better names) will just be extensions on the MVC builder. That replace their respective IFooActivator with an implementation using DI.

Using Multiple Projects/Assemblies

We want to make it easier to compose MVC's default behavior with the kinds of startup-configured apps that developers have been asking for. We also want to simplify some scenarios around creating redistributable components that provide content/views/controllers.

To accomplish this, we're going to provide a new configurable item on MvcOptions - ApplicationParts. There is basically a 1-1 mapping between an Application Part and and an assembly. Startup code that modifies MvcOptions will see MvcOptions.ApplicationParts pre-populated with an entry for each assembly we'd consider as an "MVC" assembly by default.

You'll also be able to modify an individual Part to do things like include/exclude controllers and view components. We also want to add more goodies here, like the ability to auto-detect that an assembly contains embedded Razor sources or precompiled views.

The Complication

The complication is that Application Parts need to expose and interact with arbitrary features, including types we don't reference from Mvc.Core.

We'll want Application Parts to support a feature-collection-like pattern

Examples

AddMvc(options =>
{
    // Load and use all assemblies in the Plugins directory
    options.ApplicationParts.AddRange(Directory.EnumerateFiles(".../Plugins/*.dll").Select(f => Assembly.Load(f));
})
.AddControllersAsServices(); // Use DI for activation
// Example 3rd party component
public static IMvcBuilder AddBlog(this IMvcBuilder builder)
{
    builder.AddMvcOptions(options =>
    {
        options.ApplicationParts.Add("Blog", typeof(Blog).Assembly);
    });
}

AddMvc().AddBlog().AddMvcOptions(options =>
{
    // Don't use embedded views from this assembly
    options.ApplicationParts["Blog"].SetEmbeddedRazorFileProvider(null); 
})

API Skeleton

public class MvcOptions
{
    public ApplicationPartsCollection ApplicationParts { get; }

    ...
}
public class ApplicationPartsCollection : Collection<ApplicationPart>
{
    public void Add(Assembly assembly)
    public void Add(ApplicationPart part)

    public void AddFeature(IApplicationPartFeatureProvider feature);
}
public class ApplicationPart
{
    public ApplicationPart(Assembly assembly);

    public void SetFeature(IApplicationPartFeature feature);
    public void GetFeature<TFeature>();
}
public interface IControllerFeature
{
    IList<TypeInfo> ControllerTypes { get; }
}
public static class ControllerFeatureApplicationPartExtensions
{
    public static IList<TypeInfo> GetControllerTypes(this ApplicationPart part);
}

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions