.NET
MEF
System.AddIn
MAF
software development

Choosing between MEF and MAF System.AddIn

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

MEF and MAF both support extensibility in .NET, but they solve different problems. MEF is mainly about discovering and composing parts inside one application, while MAF, exposed through System.AddIn, is about stronger plugin isolation, version resilience, and controlled boundaries between a host and third-party add-ins.

Start with the real question: composition or isolation

If your plugins are trusted application components and you mainly want flexible discovery and wiring, MEF is usually the simpler choice. If your add-ins are developed independently, may need stronger isolation, or must survive host and add-in version changes, MAF is the more appropriate design.

That distinction matters more than a feature checklist.

MEF is good at:

  • runtime discovery of exports
  • dependency composition
  • low ceremony for modular applications

MAF is good at:

  • explicit host-addin contracts
  • version-tolerant plugin pipelines
  • loading add-ins across isolation boundaries

The cost is complexity. MAF asks you to define contracts, views, and adapters because it is solving a harder stability problem.

MEF is simpler for in-process extensibility

A minimal MEF example looks like this:

csharp
1using System;
2using System.ComponentModel.Composition;
3using System.ComponentModel.Composition.Hosting;
4
5public interface IMessageProvider
6{
7    string GetMessage();
8}
9
10[Export(typeof(IMessageProvider))]
11public class HelloProvider : IMessageProvider
12{
13    public string GetMessage() => "Hello from MEF";
14}
15
16public class Program
17{
18    [Import]
19    public IMessageProvider Provider { get; set; } = null!;
20
21    public static void Main()
22    {
23        var program = new Program();
24        var catalog = new AssemblyCatalog(typeof(Program).Assembly);
25        var container = new CompositionContainer(catalog);
26        container.ComposeParts(program);
27
28        Console.WriteLine(program.Provider.GetMessage());
29    }
30}

This is attractive because the composition model is direct. If your extensibility story is "find implementations and wire them together," MEF is a good fit.

MAF is heavier, but built for safer plugin boundaries

MAF uses a pipeline architecture with contracts and adapters. That indirection is what lets the host and add-in evolve more independently.

A simplified contract might look like this:

csharp
1using System.AddIn.Contract;
2
3public interface IMessageContract : IContract
4{
5    string GetMessage();
6}

In a real MAF application, you then build host views, add-in views, and adapters between them. That is more code than MEF, but it gives you explicit boundaries. Historically, that made MAF attractive for applications that host external add-ins and care deeply about stability.

How to choose in practice

Choose MEF when:

  • plugins are trusted and run in the same process
  • you want simple discovery and composition
  • dependency management is the main challenge

Choose MAF when:

  • add-ins come from external parties
  • isolation and versioning matter more than simplicity
  • you are willing to pay pipeline complexity for safety

One practical rule is that if you do not already know why you need MAF's isolation model, you probably want MEF.

Consider the platform context too

MAF belongs to the older System.AddIn model and is mostly relevant in classic .NET Framework style applications. In many modern .NET systems, teams instead combine dependency injection, assembly loading, IPC, or process isolation to get a plugin architecture that fits current runtime constraints.

That does not make the old distinction wrong. It just means the decision is partly architectural and partly platform-specific. The important idea remains the same: MEF optimizes composition, MAF optimizes boundaries.

Common Pitfalls

The biggest mistake is choosing MAF because it sounds more "enterprise" without actually needing isolation. You end up with extra contracts and adapters solving a problem the application never had.

The opposite mistake is choosing MEF for untrusted or independently versioned third-party plugins and then discovering too late that in-process composition is not enough protection.

Teams also confuse discovery with isolation. MEF discovers parts well, but it does not provide the same host-addin boundary guarantees that motivated MAF.

Finally, do not ignore runtime support and maintenance reality. A design that looks elegant on paper may not fit the target .NET platform or deployment model.

Summary

  • MEF is primarily for composition and runtime discovery inside an application.
  • MAF, through System.AddIn, is primarily for stronger plugin isolation and version tolerance.
  • MEF is simpler and usually the better fit for trusted in-process extensibility.
  • MAF is heavier but more appropriate when host-addin boundaries matter.
  • In modern .NET, also evaluate whether custom loading or process isolation fits better than either framework.

Course illustration
Course illustration

All Rights Reserved.