public override IEnumerable<CompositionDependency> GetDependencies(TypeInfo partType, DependencyAccessor definitionAccessor) { var partTypeAsType = partType.AsType(); var imports = (from pi in partTypeAsType.GetRuntimeProperties() .Where(pi => pi.CanWrite && pi.SetMethod.IsPublic && !(pi.SetMethod.IsStatic)) let attrs = _attributeContext.GetDeclaredAttributes(pi.DeclaringType, pi).ToArray() let site = new PropertyImportSite(pi) where attrs.Any(a => a is ImportAttribute || a is ImportManyAttribute) select new { Site = site, ImportInfo = ContractHelpers.GetImportInfo(pi.PropertyType, attrs, site) }).ToArray(); if (imports.Length == 0) return NoDependencies; var result = new List<CompositionDependency>(); foreach (var i in imports) { if (!i.ImportInfo.AllowDefault) { result.Add(definitionAccessor.ResolveRequiredDependency(i.Site, i.ImportInfo.Contract, false)); } else { CompositionDependency optional; if (definitionAccessor.TryResolveOptionalDependency(i.Site, i.ImportInfo.Contract, false, out optional)) result.Add(optional); // Variation from CompositionContainer behaviour: we don't have to support recomposition // so we don't require that defaultable imports be set to null. } } return result; }
public override IEnumerable<ExportDescriptorPromise> GetExportDescriptors( CompositionContract contract, DependencyAccessor dependencyAccessor) { if (contract == null) throw new ArgumentNullException("contract"); if (dependencyAccessor == null) throw new ArgumentNullException("dependencyAccessor"); string key; CompositionContract unwrapped; if (!contract.TryUnwrapMetadataConstraint(SettingKey, out key, out unwrapped) || !unwrapped.Equals(new CompositionContract(unwrapped.ContractType)) || !SupportedSettingTypes.Contains(unwrapped.ContractType) || !ConfigurationManager.AppSettings.AllKeys.Contains(key)) yield break; var value = ConfigurationManager.AppSettings.Get(key); var converted = Convert.ChangeType(value, contract.ContractType); yield return new ExportDescriptorPromise( contract, "System.Configuration.ConfigurationManager.AppSettings", true, NoDependencies, _ => ExportDescriptor.Create((c, o) => converted, NoMetadata)); }
/// <summary> /// <see cref="ILogger"/>生成処理 /// /// https://mef.codeplex.com/wikipage?title=ProgrammingModelExtensions&referringTitle=Documentation /// </summary> /// <param name="contract"></param> /// <param name="descriptorAccessor"></param> /// <returns></returns> public override IEnumerable<ExportDescriptorPromise> GetExportDescriptors(CompositionContract contract, DependencyAccessor descriptorAccessor) { if (contract.ContractType == typeof(ILogger)) { string value = string.Empty; CompositionContract unwrap; contract.TryUnwrapMetadataConstraint("LogType", out value, out unwrap); string header = string.Format("[{0}] LogExportDescriptorProvider - ", value); return new ExportDescriptorPromise[] { new ExportDescriptorPromise( contract, "ConsoleMef2 ILogger", true, NoDependencies, _ => ExportDescriptor.Create((c, o) => new Logger() { Header = header }, NoMetadata) ) }; } else return NoExportDescriptors; }
public override IEnumerable<ExportDescriptorPromise> GetExportDescriptors(CompositionContract contract, DependencyAccessor descriptorAccessor) { if (contract == null) throw new ArgumentNullException("contract"); if (descriptorAccessor == null) throw new ArgumentNullException("descriptorAccessor"); string name; CompositionContract unwrapped; var connectionStringSettings = ConfigurationManager.ConnectionStrings.OfType<ConnectionStringSettings>().ToArray(); if (!contract.TryUnwrapMetadataConstraint(NameKey, out name, out unwrapped) || !unwrapped.Equals(new CompositionContract(unwrapped.ContractType)) || !(unwrapped.ContractType == typeof(string) || typeof(DbConnectionStringBuilder).IsAssignableFrom(unwrapped.ContractType)) || !connectionStringSettings.Any(cs => cs.Name == name)) yield break; var stringValue = connectionStringSettings.Single(cs => cs.Name == name).ConnectionString; object value = stringValue; if (contract.ContractType != typeof(string)) { var stringBuilder = Activator.CreateInstance(contract.ContractType) as DbConnectionStringBuilder; if (stringBuilder == null) yield break; stringBuilder.ConnectionString = stringValue; value = stringBuilder; } yield return new ExportDescriptorPromise( contract, "System.Configuration.ConfigurationManager.ConnectionStrings", true, NoDependencies, _ => ExportDescriptor.Create((c, o) => value, NoMetadata)); }
/// <summary> /// Promise export descriptors for the specified export key. /// </summary> /// <param name="contract">The export key required by another component.</param><param name="descriptorAccessor">Accesses the other export descriptors present in the composition.</param> /// <returns> /// Promises for new export descriptors. /// </returns> /// <remarks> /// A provider will only be queried once for each unique export key. /// The descriptor accessor can only be queried immediately if the descriptor being promised is an adapter, such as /// <see cref="T:System.Lazy`1"/>; otherwise, dependencies should only be queried within execution of the function provided /// to the <see cref="T:System.Composition.Hosting.Core.ExportDescriptorPromise"/>. The actual descriptors provided should not close over or reference any /// aspect of the dependency/promise structure, as this should be able to be GC'ed. /// </remarks> public override IEnumerable<ExportDescriptorPromise> GetExportDescriptors(CompositionContract contract, DependencyAccessor descriptorAccessor) { var isSupported = this.servicesSupport.GetOrAdd( contract.ContractType, type => this.serviceProvider.GetService(type) != null); if (!isSupported) { return ExportDescriptorProvider.NoExportDescriptors; } return new[] { new ExportDescriptorPromise( contract, contract.ContractType.Name, true, // is shared ExportDescriptorProvider.NoDependencies, dependencies => ExportDescriptor.Create( (c, o) => { var instance = this.serviceProvider.GetService(contract.ContractType); var disposable = instance as IDisposable; if (disposable != null) { c.AddBoundInstance(disposable); } return instance; }, ExportDescriptorProvider.NoMetadata)) }; }
public override IEnumerable<ExportDescriptorPromise> GetExportDescriptors(CompositionContract contract, DependencyAccessor descriptorAccessor) { // Avoid trying to create defaults-of-defaults-of... if (contract.ContractName != null && contract.ContractName.StartsWith(Constants.DefaultContractNamePrefix)) return NoExportDescriptors; var implementations = descriptorAccessor.ResolveDependencies("test for default", contract, false); if (implementations.Any()) return NoExportDescriptors; var defaultImplementationDiscriminator = Constants.DefaultContractNamePrefix + (contract.ContractName ?? ""); IDictionary<string, object> copiedConstraints = null; if (contract.MetadataConstraints != null) copiedConstraints = contract.MetadataConstraints.ToDictionary(k => k.Key, k => k.Value); var defaultImplementationContract = new CompositionContract(contract.ContractType, defaultImplementationDiscriminator, copiedConstraints); CompositionDependency defaultImplementation; if (!descriptorAccessor.TryResolveOptionalDependency("default", defaultImplementationContract, true, out defaultImplementation)) return NoExportDescriptors; return new[] { new ExportDescriptorPromise( contract, "Default Implementation", false, () => new[] {defaultImplementation}, _ => { var defaultDescriptor = defaultImplementation.Target.GetDescriptor(); return ExportDescriptor.Create((c, o) => defaultDescriptor.Activator(c, o), defaultDescriptor.Metadata); }) }; }
public CompositionDependency[] GetDependencies(DependencyAccessor definitionAccessor) { return GetPartActivatorDependencies(definitionAccessor) .Concat(_activationFeatures .SelectMany(feature => feature.GetDependencies(_partType, definitionAccessor))) .Where(a => a != null) .ToArray(); }
public override IEnumerable<ExportDescriptorPromise> GetExportDescriptors( CompositionContract contract, DependencyAccessor descriptorAccessor ) { // var type = convention( contract.ContractType ) ?? contract.ContractType; contract.ContractType .Append( convention( contract.ContractType ) ) .WhereAssigned() .Distinct() .Each( Initializer ); yield break; }
public override IEnumerable<ExportDescriptorPromise> GetExportDescriptors(CompositionContract contract, DependencyAccessor descriptorAccessor) { if (!contract.Equals(_supportedContract)) return NoExportDescriptors; var implementations = descriptorAccessor.ResolveDependencies("test for existing", contract, false); if (implementations.Any()) return NoExportDescriptors; return new[] { new ExportDescriptorPromise(contract, "test metadataProvider", false, NoDependencies, _ => ExportDescriptor.Create((c, o) => DefaultObject, NoMetadata)) }; }
public override IEnumerable<ExportDescriptorPromise> GetExportDescriptors(CompositionContract contract, DependencyAccessor definitionAccessor) { if (!contract.Equals(s_currentScopeContract)) return NoExportDescriptors; return new[] { new ExportDescriptorPromise( contract, typeof(CompositionContext).Name, true, NoDependencies, _ => ExportDescriptor.Create((c, o) => c, NoMetadata)) }; }
private IEnumerable<CompositionDependency> GetPartActivatorDependencies(DependencyAccessor definitionAccessor) { var partTypeAsType = _partType.AsType(); if (_constructor == null) { foreach (var c in _partType.DeclaredConstructors.Where(ci => ci.IsPublic && !(ci.IsStatic))) { if (_attributeContext.GetDeclaredAttribute<ImportingConstructorAttribute>(partTypeAsType, c) != null) { if (_constructor != null) { var message = string.Format(Properties.Resources.DiscoveredPart_MultipleImportingConstructorsFound, _partType); throw new CompositionFailedException(message); } _constructor = c; } } if (_constructor == null) _constructor = _partType.DeclaredConstructors .FirstOrDefault(ci => ci.IsPublic && !(ci.IsStatic || ci.GetParameters().Any())); if (_constructor == null) { var message = string.Format(Properties.Resources.DiscoveredPart_NoImportingConstructorsFound, _partType); throw new CompositionFailedException(message); } } var cps = _constructor.GetParameters(); for (var i = 0; i < cps.Length; ++i) { var pi = cps[i]; var site = new ParameterImportSite(pi); var importInfo = ContractHelpers.GetImportInfo(pi.ParameterType, _attributeContext.GetDeclaredAttributes(partTypeAsType, pi), site); if (!importInfo.AllowDefault) { yield return definitionAccessor.ResolveRequiredDependency(site, importInfo.Contract, true); } else { CompositionDependency optional; if (definitionAccessor.TryResolveOptionalDependency(site, importInfo.Contract, true, out optional)) yield return optional; } } }
public ExportDescriptorPromise GetExportDescriptorPromise( CompositionContract contract, DependencyAccessor definitionAccessor) { return new ExportDescriptorPromise( contract, Part.PartType.Name, Part.IsShared, () => Part.GetDependencies(definitionAccessor), deps => { var activator = Part.GetActivator(definitionAccessor, deps); return GetExportDescriptor(activator); }); }
public override IEnumerable<ExportDescriptorPromise> GetExportDescriptors(CompositionContract contract, DependencyAccessor definitionAccessor) { DiscoverGenericParts(contract); DiscoverConstrainedParts(contract); ICollection<DiscoveredExport> forKey; if (!_discoveredParts.TryGetValue(contract, out forKey)) return NoExportDescriptors; // Exports with metadata may be matched via metadata constraints. // It should be possible to do this more aggressively by changing the way // exports are stored. if (!forKey.Any(x => x.Metadata.Any())) { // Allow some garbage to be collected _discoveredParts.Remove(contract); } return forKey.Select(de => de.GetExportDescriptorPromise(contract, definitionAccessor)).ToArray(); }
/// <summary> /// Promise export descriptors for the specified export key. /// </summary> /// <param name="contract">The export key required by another component.</param> /// <param name="descriptorAccessor">Accesses the other export descriptors present in the composition.</param> /// <returns>Promises for new export descriptors.</returns> /// <remarks> /// A provider will only be queried once for each unique export key. /// The descriptor accessor can only be queried immediately if the descriptor being promised is an adapter, such as /// <see cref="Lazy{T}"/>; otherwise, dependencies should only be queried within execution of the function provided /// to the <see cref="ExportDescriptorPromise"/>. The actual descriptors provided should not close over or reference any /// aspect of the dependency/promise structure, as this should be able to be GC'ed. /// </remarks> public abstract IEnumerable <ExportDescriptorPromise> GetExportDescriptors( CompositionContract contract, DependencyAccessor descriptorAccessor);
/// <summary> /// Describe the dependencies required by this activation feature. /// </summary> /// <param name="partType">The part type being activated.</param> /// <param name="definitionAccessor">The definition accessor.</param> /// <returns>Dependencies.</returns> public virtual IEnumerable<CompositionDependency> GetDependencies(TypeInfo partType, DependencyAccessor definitionAccessor) { return NoDependencies; }
public override IEnumerable<ExportDescriptorPromise> GetExportDescriptors(CompositionContract contract, DependencyAccessor descriptorAccessor) { if (IsSupportedContract(contract)) yield return new ExportDescriptorPromise(contract, "factory delegate", true, NoDependencies, _ => ExportDescriptor.Create(activator, Metadata)); }
public CompositeActivator GetActivator(DependencyAccessor definitionAccessor, IEnumerable<CompositionDependency> dependencies) { if (_partActivator != null) return _partActivator; var contextParam = Expression.Parameter(typeof(LifetimeContext), "cc"); var operationParm = Expression.Parameter(typeof(CompositionOperation), "op"); var cps = _constructor.GetParameters(); Expression[] paramActivatorCalls = new Expression[cps.Length]; var partActivatorDependencies = dependencies .Where(dep => dep.Site is ParameterImportSite) .ToDictionary(d => ((ParameterImportSite)d.Site).Parameter); for (var i = 0; i < cps.Length; ++i) { var pi = cps[i]; CompositionDependency dep; if (partActivatorDependencies.TryGetValue(pi, out dep)) { var a = dep.Target.GetDescriptor().Activator; paramActivatorCalls[i] = Expression.Convert(Expression.Call(Expression.Constant(a), s_activatorInvoke, contextParam, operationParm), pi.ParameterType); } else { paramActivatorCalls[i] = Expression.Default(pi.ParameterType); } } Expression body = Expression.Convert(Expression.New(_constructor, paramActivatorCalls), typeof(object)); var activator = Expression .Lambda<CompositeActivator>(body, contextParam, operationParm) .Compile(); foreach (var activationFeature in _activationFeatures) activator = activationFeature.RewriteActivator(_partType, activator, _partMetadata.Value, dependencies); _partActivator = activator; return _partActivator; }
public override IEnumerable<ExportDescriptorPromise> GetExportDescriptors(CompositionContract contract, DependencyAccessor descriptorAccessor) { if (IsSupportedContract(contract)) yield return new ExportDescriptorPromise(contract, this.exportedInstance.ToString(), true, NoDependencies, _ => ExportDescriptor.Create((c, o) => exportedInstance, Metadata)); }
/// <summary> /// Promise export descriptors for the specified export key. /// </summary> /// <param name="contract">The export key required by another component.</param> /// <param name="descriptorAccessor">Accesses the other export descriptors present in the composition.</param> /// <returns>Promises for new export descriptors.</returns> /// <remarks> /// A provider will only be queried once for each unique export key. /// The descriptor accessor can only be queried immediately if the descriptor being promised is an adapter, such as /// <see cref="Lazy{T}"/>; otherwise, dependencies should only be queried within execution of the function provided /// to the <see cref="ExportDescriptorPromise"/>. The actual descriptors provided should not close over or reference any /// aspect of the dependency/promise structure, as this should be able to be GC'ed. /// </remarks> public abstract IEnumerable<ExportDescriptorPromise> GetExportDescriptors( CompositionContract contract, DependencyAccessor descriptorAccessor);