N-Layer using MEF dependency injection on MVC project I'm trying to create a "perfect" generic solution structure for MVC (5.2.3.0) projects using MEF.

Currently my solution looks like this.




Core layer contains generic classes that could be used in any project
Data layer contains a ApplicationContext (: DbContext) and models
Repositories layer contains Repository classes to access data
Service layer contains business rules
TreeOfMana is the presentation (MVC)
Dependencies is where I'm adding all interfaces (IUser, IRepository, IApplicationContext...)


They don't know each other



The layers "export" their DLLs on the Post Build event to the presentation bin folder.

copy "$(TargetFileName)" "$(SolutionDir)$(SolutionName)\bin"


This allows me to load assemblies and add to MEF

public static class MefConfig
{
    public static CompositionContainer Container { get; private set; }

    public static void Register()
    {
        var files = Directory.GetFiles(AppDomain.CurrentDomain.BaseDirectory, "TreeOfMana*.dll", SearchOption.AllDirectories)
            .Where(o =&gt; !o.Replace(AppDomain.CurrentDomain.BaseDirectory, "").Contains("obj\\"));

        var catalogAggregator = new AggregateCatalog();

        foreach (var file in files)
        {
            catalogAggregator.Catalogs.Add(new AssemblyCatalog(Assembly.LoadFrom(file)));
        }

        Container = new CompositionContainer(catalogAggregator);
    }
}


To wire-up with MVC I'm using a custom controller factory. For that first I need to export the controller:

public class ControllerExportAttribute : ExportAttribute
{
    public ControllerExportAttribute(Type concreteType)
        : base(concreteType.FullName, typeof(IController))
    {

    }
}

[ControllerExportAttribute(typeof(HomeController))]
[PartCreationPolicy(System.ComponentModel.Composition.CreationPolicy.NonShared)]
public class HomeController : Controller { }


By exporting as IController and having the contract name I can find it on the exports list. 

My ControllerFactory is:

public class MefControllerFactory : DefaultControllerFactory
{
    private readonly CompositionContainer compositionContainer;

    public MefControllerFactory(CompositionContainer compositionContainer)
    {
        this.compositionContainer = compositionContainer;
    }

    protected override IController GetControllerInstance(System.Web.Routing.RequestContext requestContext, Type controllerType)
    {
        IController result = null;

        var export = compositionContainer.GetExports(typeof(IController), null, controllerType.FullName).SingleOrDefault();

        if (null != export)
            result = export.Value as IController;

        if (null != result)
            compositionContainer.SatisfyImportsOnce(result);

        return result;
    }
}


The controller factory finds the exported controller where the contract name ends with the controller name requested.

Question

I'm looking for advice on how to separate the layers, how to properly use MEF on an architecture like this.


Does this structure I created look decent? 
Does it make sense? 
Should I change something? 
Am I going mad?
Security

MEF is a lightweight framework for discovering plugins at runtime. Be wary that plugins are loaded using the same security and evidence of the container code. Anyone deploying malicious TreeOfMana*.ddl in your output folder has the same access rights to the system as your application.


var files = Directory.GetFiles(
    AppDomain.CurrentDomain.BaseDirectory, "TreeOfMana*.dll",
        SearchOption.AllDirectories)
            .Where(o =&gt; !o.Replace(AppDomain.CurrentDomain.BaseDirectory,
                 "").Contains("obj\\"));



MAF comes with built-in functionality to provide separate and limited permissions for addins. But I'm not sure whether or to which degree this framework is still supported. If you keep using MEF, make sure no malicious code could get access to the system. Some considerations:


Assembly Security
Create a dedicated Application Domain for running plugins
You could create custom authentication with DLL license keys