Language: C#
A conventional catalog for MEF (Prototype)
using System; using System.ComponentModel.Composition.Primitives; using System.Collections.Generic; using System.ComponentModel.Composition.ReflectionModel; using System.ComponentModel.Composition; using System.Reflection; using System.Linq; using System.ComponentModel.Composition.Hosting; using System.Collections; namespace Microsot.ComponentModel.Composition { public class ConventionalCatalog : ComposablePartCatalog { private List<ComposablePartDefinition> _parts = new List<ComposablePartDefinition>(); public void RegisterType<TImplementation, TContract>() { 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>>(() => new Dictionary<string, object>()), null); this._parts.Add(part); } 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); } } } //sample parts and contracts public interface IRule { } public interface IRulesEngine { } public interface ILogger { } public class Logger : ILogger { } public class Rule1 : IRule { private ILogger _logger; public Rule1(ILogger logger) { _logger = logger; } } public class Rule2 : IRule { private ILogger _logger; public Rule2(ILogger logger) { _logger = logger; } } public class RulesEngine { private IEnumerable<Lazy<IRule>> _rules; public RulesEngine (IEnumerable<Lazy<IRule>> rules) { _rules = rules; } } //Sample public class Test { public Test() { var catalog = new ConventionalCatalog(); catalog.RegisterType<Rule1, IRule>(); catalog.RegisterType<Rule2, IRule>(); catalog.RegisterType<Logger, ILogger>(); catalog.RegisterType<RulesEngine, RulesEngine>(); var container = new CompositionContainer(catalog); var engine = container.GetExportedValue<RulesEngine>(); } }
Tags:
Description:
Prototype of a MEF POCO catalog. Uses our ReflectionModelServices api to configure through conventions. Supports Lazy as well.
Does not support export metadata (no way to define it), property injection, or recompostion.
Does not support export metadata (no way to define it), property injection, or recompostion.
Report Abuse
Subscribe
Discuss
What's new
What is it
New Snippet
Recent Snippets
My Snippets
Web Code
Search

