MEF Poco

Apr 30, 2009 at 8:19 AM
Edited Apr 30, 2009 at 8:19 AM
Hi guys

For some time we've been thinking about poco support for MEF. I posted recently on my blog about an approach for getting it to work.

http://codebetter.com/blogs/glenn.block/archive/2009/04/27/poco-mef-and-custom-type-systems-are-you-ready-to-take-the-red-pill.aspx

Feedback is welcome and encouraged :-)
Apr 30, 2009 at 8:45 AM
That's just AWSOME!

Creating a new type is like genesis or something! I'm gonna get into this cool code right away!

M.

On Thu, Apr 30, 2009 at 9:19 AM, gblock <notifications@codeplex.com> wrote:

From: gblock

Hi guys

For sometime we've been thinking about poco support for MEF. I posted recently on my blog about an approach for getting it to work.

http://codebetter.com/blogs/glenn.block/archive/2009/04/27/poco-mef-and-custom-type-systems-are-you-ready-to-take-the-red-pill.aspx

Feedback is welcome and encouraged :-)

Read the full discussion online.

To add a post to this discussion, reply to this email (MEF@discussions.codeplex.com)

To start a new discussion for this project, email MEF@discussions.codeplex.com

You are receiving this email because you subscribed to this discussion on CodePlex. You can unsubscribe or change your settings on codePlex.com.

Please note: Images and attachments will be removed from emails. Any posts to this discussion will also be available online at codeplex.com





--
Magnus Mårtensson
Senior Consultant - Scrum Master - MCSD, MCTS
Dotway AB

Tel: +46 (768) 51 00 36

http://blog.noop.se/
Jun 29, 2010 at 11:55 AM
Edited Jun 29, 2010 at 12:34 PM

Unfortunately the code posted at http://codebetter.com/blogs/glenn.block/archive/2009/04/27/poco-mef-and-custom-type-systems-are-you-ready-to-take-the-red-pill.aspx only compiles for .Net, but not for Silverlight.

If anyone needs a SL-compatible POCO MEF catalog that also supports CreationPolicy, here is a sample (based on http://codepaste.net/yadusn):

 

   public class ConventionalCatalog : ComposablePartCatalog
    {
        private List<ComposablePartDefinition> _parts = new List<ComposablePartDefinition>();

        public void RegisterType<TImplementation, TContract>(CreationPolicy policy)
        {
            var part = ReflectionModelServices.CreatePartDefinition(
                new Lazy<Type>(() => typeof(TImplementation)),
                false,
                new Lazy<IEnumerable<ImportDefinition>>(() => GetImportDefinitions(typeof(TImplementation))),
                new Lazy<IEnumerable<ExportDefinition>>(() => GetExportDefinitions(typeof(TImplementation), typeof(TContract))),
                new Lazy<IDictionary<string, object>>(() => GetPartMetdata(policy)),
                null);

            this._parts.Add(part);
        }

        private IDictionary<string, object> GetPartMetdata(CreationPolicy policy)
        {
            var md = new Dictionary<string, object>();
            md.Add(CompositionConstants.PartCreationPolicyMetadataName, policy);
            return md;
        }

        private ImportDefinition[] GetImportDefinitions(Type implementationType)
        {
            var constructors = implementationType.GetConstructors()[0];
            var imports = new List<ImportDefinition>();

            foreach (var param in constructors.GetParameters())
            {
                var cardinality = GetCardinality(param);
                var importType = cardinality == ImportCardinality.ZeroOrMore ? GetCollectionContractType(param.ParameterType) : param.ParameterType;

                imports.Add(
                    ReflectionModelServices.CreateImportDefinition(
                        new Lazy<ParameterInfo>(() => param),
                        AttributedModelServices.GetContractName(importType),
                        AttributedModelServices.GetTypeIdentity(importType),
                        Enumerable.Empty<KeyValuePair<string, Type>>(),
                        cardinality,
                        CreationPolicy.Any,
                        null));

            }
            return imports.ToArray();
        }

        private ImportCardinality GetCardinality(ParameterInfo param)
        {
            if (typeof(IEnumerable).IsAssignableFrom(param.ParameterType))
                return ImportCardinality.ZeroOrMore;
            else
                return ImportCardinality.ExactlyOne;
        }

        //This is hacky! Needs to be cleaned up as it makes many assumptions.
        private Type GetCollectionContractType(Type collectionType)
        {
            var itemType = collectionType.GetGenericArguments().First();
            var contractType = itemType.GetGenericArguments().First();
            return contractType;
        }

        private ExportDefinition[] GetExportDefinitions(Type implementationType, Type contractType)
        {
            var lazyMember = new LazyMemberInfo(implementationType);
            var contracName = AttributedModelServices.GetContractName(contractType);
            var metadata = new Lazy<IDictionary<string, object>>(() =>
            {
                var md = new Dictionary<string, object>();
                md.Add(CompositionConstants.ExportTypeIdentityMetadataName, AttributedModelServices.GetTypeIdentity(contractType));
                return md;
            });

            return new ExportDefinition[] { ReflectionModelServices.CreateExportDefinition(lazyMember, contracName, metadata, null) };
        }

        public override IQueryable<ComposablePartDefinition> Parts
        {
            get
            {
                return this._parts.AsQueryable();
            }
        }

        public override IEnumerable<Tuple<ComposablePartDefinition, ExportDefinition>> GetExports(ImportDefinition definition)
        {
            return base.GetExports(definition);
        }
    }

Jun 29, 2010 at 6:53 PM

Check out MefContrib. There is a convention based programming model that works on SL. Here is also a very simplified example of how you can achieve poco using our ReflectionModelServices api which works on SL and which MefContrib uses. http://codepaste.net/yadusn

Hope this helps

Glenn

From: qs7000 [mailto:notifications@codeplex.com]
Sent: Tuesday, June 29, 2010 3:56 AM
To: Glenn Block
Subject: Re: MEF Poco [MEF:54914]

From: qs7000

Unfortunately the code posted at http://codebetter.com/blogs/glenn.block/archive/2009/04/27/poco-mef-and-custom-type-systems-are-you-ready-to-take-the-red-pill.aspx only compiles for .Net, but not for Silverlight.

While there are some SL-compatible MEF POCO containers out there (e.g. http://blogs.msdn.com/nblumhardt/archive/2009/03/16/hosting-mef-extensions-in-an-ioc-container.aspx), the problem with these is that they do not support setting the CreationPolicy, so you always get singletons.

Is there some MEF POCO container for SL that does support setting the CreationPolicy for exports?

Read the full discussion online.

To add a post to this discussion, reply to this email (MEF@discussions.codeplex.com)

To start a new discussion for this project, email MEF@discussions.codeplex.com

You are receiving this email because you subscribed to this discussion on CodePlex. You can unsubscribe or change your settings on codePlex.com.

Please note: Images and attachments will be removed from emails. Any posts to this discussion will also be available online at codeplex.com

Jun 29, 2010 at 6:53 PM

Btw, contrib is at mefcontrib.codeplex.com.

From: qs7000 [mailto:notifications@codeplex.com]
Sent: Tuesday, June 29, 2010 3:56 AM
To: Glenn Block
Subject: Re: MEF Poco [MEF:54914]

From: qs7000

Unfortunately the code posted at http://codebetter.com/blogs/glenn.block/archive/2009/04/27/poco-mef-and-custom-type-systems-are-you-ready-to-take-the-red-pill.aspx only compiles for .Net, but not for Silverlight.

While there are some SL-compatible MEF POCO containers out there (e.g. http://blogs.msdn.com/nblumhardt/archive/2009/03/16/hosting-mef-extensions-in-an-ioc-container.aspx), the problem with these is that they do not support setting the CreationPolicy, so you always get singletons.

Is there some MEF POCO container for SL that does support setting the CreationPolicy for exports?

Read the full discussion online.

To add a post to this discussion, reply to this email (MEF@discussions.codeplex.com)

To start a new discussion for this project, email MEF@discussions.codeplex.com

You are receiving this email because you subscribed to this discussion on CodePlex. You can unsubscribe or change your settings on codePlex.com.

Please note: Images and attachments will be removed from emails. Any posts to this discussion will also be available online at codeplex.com