private static ExportInfo[] GetExportsFromExportManyAttribute(ExportedRegistrationInfo currentInfo, Type implementationType, ExportManyAttribute exportManyAttribute) { var contractTypes = Registrator.GetImplementedServiceTypes(implementationType, exportManyAttribute.NonPublic); if (!exportManyAttribute.Except.IsNullOrEmpty()) { contractTypes = contractTypes.Except(exportManyAttribute.Except).ToArrayOrSelf(); } var manyExports = contractTypes .Select(t => new ExportInfo(t, exportManyAttribute.ContractName ?? exportManyAttribute.ContractKey)) .ToArray(); Throw.If(manyExports.Length == 0, Error.ExportManyDoesNotExportAnyType, implementationType, contractTypes); var currentExports = currentInfo.Exports; if (!currentExports.IsNullOrEmpty()) { for (var i = 0; i < currentExports.Length; i++) { if (!manyExports.Contains(currentExports[i])) { manyExports = manyExports.AppendOrUpdate(currentExports[i]); } } } return(manyExports); }
private static void RegisterFactoryMethods(IRegistrator registrator, ExportedRegistrationInfo factoryInfo) { // NOTE: Cast is required for NET35 var members = factoryInfo.ImplementationType.GetAll(t => t.DeclaredMethods.Cast <MemberInfo>().Concat( t.DeclaredProperties.Cast <MemberInfo>().Concat( t.DeclaredFields.Cast <MemberInfo>()))); foreach (var member in members) { var attributes = member.GetAttributes().ToArrayOrSelf(); if (!IsExportDefined(attributes)) { continue; } var memberReturnType = member.GetReturnTypeOrDefault(); var registrationInfo = GetRegistrationInfoOrDefault(memberReturnType, attributes).ThrowIfNull(); var factoryExport = factoryInfo.Exports[0]; var factoryServiceInfo = member.IsStatic() ? null : ServiceInfo.Of(factoryExport.ServiceType, IfUnresolved.ReturnDefault, factoryExport.ServiceKeyInfo.Key); var factoryMethod = FactoryMethod.Of(member, factoryServiceInfo); var factory = registrationInfo.CreateFactory(Made.Of(_ => factoryMethod)); var serviceExports = registrationInfo.Exports; for (var i = 0; i < serviceExports.Length; i++) { var export = serviceExports[i]; registrator.Register(factory, export.ServiceType, export.ServiceKeyInfo.Key, IfAlreadyRegistered.AppendNotKeyed, false); } } }
private static void PopulateWrapperInfoFromAttribute(ExportedRegistrationInfo resultInfo, AsWrapperAttribute attribute, Type implementationType) { Throw.If(resultInfo.FactoryType != FactoryType.Service, Error.UnsupportedMultipleFactoryTypes, implementationType); resultInfo.FactoryType = FactoryType.Wrapper; resultInfo.Wrapper = new WrapperInfo { WrappedServiceType = attribute.WrappedContractType, WrappedServiceTypeGenericArgIndex = attribute.ContractTypeGenericArgIndex }; }
private static void PopulateDecoratorInfoFromAttribute(ExportedRegistrationInfo resultInfo, AsDecoratorAttribute attribute, Type implementationType) { Throw.If(resultInfo.FactoryType != FactoryType.Service, Error.UnsupportedMultipleFactoryTypes, implementationType); resultInfo.FactoryType = FactoryType.Decorator; var decoratedServiceKeyInfo = ServiceKeyInfo.Of(attribute.ContractName ?? attribute.ContractKey); resultInfo.Decorator = new DecoratorInfo { DecoratedServiceKeyInfo = decoratedServiceKeyInfo }; }
private static ExportInfo[] GetExportsFromExportAttribute(ExportAttribute attribute, ExportedRegistrationInfo currentInfo, Type implementationType) { var export = new ExportInfo(attribute.ContractType ?? implementationType, attribute.ContractName ?? (attribute is ExportWithKeyAttribute ? ((ExportWithKeyAttribute)attribute).ContractKey : null)); var currentExports = currentInfo.Exports; var exports = currentExports == null ? new[] { export } : currentExports.Contains(export) ? currentExports : currentExports.AppendOrUpdate(export); return(exports); }
/// <summary>Registers factories into registrator/container based on single provided info, which could /// contain multiple exported services with single implementation.</summary> /// <param name="registrator">Container to register into.</param> /// <param name="info">Registration information provided.</param> public static void RegisterInfo(this IRegistrator registrator, ExportedRegistrationInfo info) { if (!info.ImplementationType.IsStatic()) { var factory = info.CreateFactory(); for (var i = 0; i < info.Exports.Length; i++) { var export = info.Exports[i]; registrator.Register(factory, export.ServiceType, export.ServiceKeyInfo.Key, IfAlreadyRegistered.AppendNotKeyed, false); } } if (info.IsFactory) { RegisterFactoryMethods(registrator, info); } }
private static ExportedRegistrationInfo GetRegistrationInfoOrDefault(Type implementationType, Attribute[] attributes) { if (implementationType.IsOpenGeneric()) { implementationType = implementationType.GetGenericTypeDefinition(); } var info = new ExportedRegistrationInfo { ImplementationType = implementationType, ReuseType = DefaultReuseType }; for (var attrIndex = 0; attrIndex < attributes.Length; attrIndex++) { var attribute = attributes[attrIndex]; if (attribute is ExportAttribute) { info.Exports = GetExportsFromExportAttribute((ExportAttribute)attribute, info, implementationType); } else if (attribute is ExportManyAttribute) { info.Exports = GetExportsFromExportManyAttribute(info, implementationType, (ExportManyAttribute)attribute); } else if (attribute is PartCreationPolicyAttribute) { var creationPolicy = ((PartCreationPolicyAttribute)attribute).CreationPolicy; info.ReuseType = creationPolicy == CreationPolicy.NonShared ? null : typeof(SingletonReuse); } else if (attribute is ReuseAttribute) { var reuseAttribute = ((ReuseAttribute)attribute); info.ReuseType = reuseAttribute.ReuseType; info.ReuseName = reuseAttribute.ReuseName; } else if (attribute is OpenResolutionScopeAttribute) { info.OpenResolutionScope = true; } else if (attribute is ReuseWrappersAttribute) { info.ReusedWrappers = ((ReuseWrappersAttribute)attribute).WrapperTypes; } else if (attribute is AsWrapperAttribute) { PopulateWrapperInfoFromAttribute(info, (AsWrapperAttribute)attribute, implementationType); } else if (attribute is AsDecoratorAttribute) { PopulateDecoratorInfoFromAttribute(info, (AsDecoratorAttribute)attribute, implementationType); } else if (attribute is ExportConditionAttribute) { info.ConditionType = attribute.GetType(); } else if (attribute is AsFactoryAttribute) { info.IsFactory = true; } if (attribute.GetType().GetAttributes(typeof(MetadataAttributeAttribute), true).Any()) { Throw.If(info.HasMetadataAttribute, Error.UnsupportedMultipleMetadata, implementationType); info.HasMetadataAttribute = true; } } if (info.FactoryType == FactoryType.Decorator) { info.ReuseType = null; } info.Exports.ThrowIfNull(Error.NoExport, implementationType); return(info); }