MEF in ASP.NET

Aug 5, 2009 at 8:51 PM

I think this may have already been asked.  But I've noticed that I can't seem to get MEF to work in an ASP.NET environment.  I've seen where one particular person has gotten it to work but it looked like there were some hoops that had to be made in order to get that to work.  What are all of your thoughts on this?  Is there a simple and intuitive way to use this technology in an ASP.NET world or even in a WCF service-based scenario?  Also, if there is a way to do this and it makes sense what are the performance implications?  By the way I basically just composed on the application start event and basically tried to do an import in a WCF service.  Thanks to anyone who would like to offer a perspective on this.

Aug 9, 2009 at 12:38 PM

Hey

I think you're right with asp.net 2.x, but with Visual Studio 2008 / 3.5sp1 it seems to work well, e.g.:

using System;
using System.Collections;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
using System.ComponentModel.Composition;
using System.Collections.Generic;
using System.ComponentModel.Composition.Hosting;
using System.Reflection;
using System.ComponentModel.Composition.Primitives;

namespace WebApplication2
{
    public partial class _Default : System.Web.UI.Page
    {
        [ImportMany(typeof(ISayHello))]
        public IEnumerable<ISayHello> HelloSayers;


        protected void Page_Load(object sender, EventArgs e)
        {
            compose();
            foreach (ISayHello say in HelloSayers)
            {
                say.Speak();
            }
        }

        private void compose()
        {
            AssemblyCatalog catalogImports = new AssemblyCatalog(Assembly.GetExecutingAssembly());
            var catalog = new AggregateCatalog(new ComposablePartCatalog[] { catalogImports});
            var container = new CompositionContainer(catalog);
            container.ComposeParts(this);
        }
    }

    [Export(typeof(ISayHello))]
    public class SayHelloToMorten : ISayHello
    {
        private String name = "Morten";
        public String Name { get { return name; } set { name = value; } }
        public void Speak()
        {
            HttpContext.Current.Response.Write("Hello " + Name);
        }
    }

    [Export(typeof(ISayHello))]
    public class SayHelloToAnders : ISayHello
    {
        private String name = "Anders";
        public String Name { get { return name; } set { name = value; } }
        public void Speak()
        {
            HttpContext.Current.Response.Write("Hello " + Name);
        }
    }

    //This interface the parts will be mutually dependent on
    public interface ISayHello
    {
        String Name { get; set; }
        void Speak();
    }

}

Aug 11, 2009 at 7:49 PM

Thank you Maate!  Do you or anyone else for that matter know what kind of performance impact there would be with having to compose with each page load?  I saw an example that tapped into the begining of and ending of each http request to perform a compose.  The only difference was that I don't think they created a new instance of the container each time.  I believe they grabbed it from http state.  This is a great example!  Thanks for taking the time to answer.