1

I'm trying to use MEF in my ASP.NET web form (SharePoint) application to load some controls from a directory at runtime. I'm not getting any error but the controls are not getting loaded.

Here is my code -

aspx.cs

    public partial class SampleMEF : System.Web.UI.Page
    {
        [ImportMany(typeof(IControlLoader))]
        IEnumerable<Lazy<IControlLoader, IControlLoaderMetaData>> controls;
        private CompositionContainer _partsContainer;
        private AggregateCatalog _catalog;
        private string _partsPath;

        /// <summary>
        /// default constructor
        /// </summary>
        public SampleMEF()
        {
        }

        /// <summary>
        /// Initialize the page
        /// </summary>
        /// <param name="e"></param>
        protected override void OnInit(EventArgs e)
        {
            _partsPath = SPUtility.GetGenericSetupPath(@"TEMPLATE\LAYOUTS\MEFProtoType\Parts");
            _catalog = new AggregateCatalog();
            DirectoryCatalog c = new DirectoryCatalog(_partsPath, "*.dll");
            _partsContainer = new CompositionContainer(c);
            _partsContainer.ComposeParts(this);
        }

        protected void Page_Load(object sender, EventArgs e)
        {
            foreach(Lazy<IControlLoader, IControlLoaderMetaData> i in controls)
            {
                SPPControl ctrl = i.Value.LoadControl();
                lbxControls.Items.Add(new ListItem(ctrl.Name, ctrl.ControlID.ToString()));
            }
        }
    }

Contracts

    /// <summary>
    /// Contract for Imports and Exports
    /// </summary>
    public interface IControlLoader
    {
        SPPControl LoadControl();
    }

    /// <summary>
    /// Exports metadata
    /// </summary>
    public interface IControlLoaderMetaData
    {
        string ControlID { get; }
    }

Sample Export

    [Export(typeof(IControlLoader))]
    [ExportMetadata("ControlID", "7a6c6288-ab52-4010-8c56-79959843ec7c")]
    public class ctrlAccordion : IControlLoader
    {
        #region IControlLoader Members

        public SPPControl LoadControl()
        {
            SPPControl ctrl = new SPPControl("Accordion", new Guid("7a6c6288-ab52-4010-8c56-79959843ec7c"), 5);
            return ctrl;
        }

        #endregion
    }

I'm able to see the DLLs copied in the parts directory. But I'm not able to load the parts. The import is not filled and it is empty.

I'm using .Net Framework 3.5 and downloaded the MEF dll from MEF Codeplex and signed the assembly myself.

Any ideas?

2 Answers 2

2

Okay, I eventually found the issue. I'm able to load the part dlls only if I sign them and add the dlls to global assembly. But I don't understand what DirectoryCatalog does loading the folder.

Bottom line: If the dlls are just in the parts folder and not in the GAC they are not getting loaded.

Sign up to request clarification or add additional context in comments.

Comments

1

There can be problems when trying to load assemblies from arbitrary locations. The "Assembly Load Issues" section of this blog post has a bit of information on this and links to more information.

You can also inspect the catalog in the debugger to see if it loaded any parts at all.

3 Comments

Yes, thats how I debugged and checked the catalog object. It just shows loaded files - 3, loaded assemblies - 0, Parts - 0. The 3 loaded files in fact are valid dlls with exports in it. But once I signed them and put it in GAC it worked!
@NLV Signing them without putting them in the GAC might also work. Giving an assembly a strong name (ie signing it) can prevent it from being loaded twice. If you had the unsigned codeplex MEF DLL in you normal bin folder and also in the parts folder, then probably two copies of the MEF DLL were being loaded, and the ExportAttrributes from your parts weren't recognized as the same as the ExportAttributes your container was looking for.
Nope. Just signing the dlls are not working. As soon as I remove the dll from the GAC I'm not able to load the parts. And also I'm just using the signed MEF dll.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.