/// <summary> /// Dynamically creates a factory of<see cref="THandler"/>s and adds to the given <see cref="dictionary"/>. /// </summary> private void AddFactory <THandler, TItem> ( IDictionary <string, IFactory <THandler, TItem> > dictionary, HandlerTypes handlerType, HandlerFactoryTypeArguments typeArgs, FieldDefinition definition ) where THandler : IFieldHandler <TItem> where TItem : class { try { Type typeDefinition = GetFactoryTypeDefinition(handlerType, typeArgs.IsCollection); Type[] typeArguments = GetFactoryTypeArgs <TItem>(typeArgs, definition).ToArray(); Type factoryType = typeDefinition.MakeGenericType(typeArguments); var autoActivator = new AutoActivator(new SubstemHandlerDependencyResolver(typeArgs.GetterExpression, definition)); var factory = (IFactory <THandler, TItem>)autoActivator.CreateInstance(factoryType); dictionary.Add(definition.FieldName, factory); } catch (Exception ex) { string message = "Cannot add " + handlerType + " factory for this " + (typeArgs.IsCollection ? "collection" : "item"); throw new StemAttributeSetupException(message, ex); } }
private IEnumerable <Type> GetFactoryTypeArgs <TItem>(HandlerFactoryTypeArguments typeArgs, FieldDefinition definition) { yield return(typeof(TItem)); yield return(typeArgs.PropertyValueType); // By convention, all the collection types have 4 generic type parameters. // The 3rd parameter is the TNav, because the property type above becomes TCollection. if (typeArgs.IsCollection) { yield return(typeArgs.EnumerableTypeArgument); } yield return(definition.SubstemType); }
public void Analyze <TItem>(EngineImplementations <TItem> implementations, FieldDefinition definition) where TItem : class { if (definition.SubstemType == null) { return; } LambdaExpression getterExpression = definition.Getter.Expression; if (getterExpression == null) { throw new StemAttributeSetupException("Substem types must be on an expression property."); } var typeArgs = new HandlerFactoryTypeArguments(); typeArgs.LoadExpression <TItem>(getterExpression); AddFactory(implementations.FullResourceFactories, HandlerTypes.FullResource, typeArgs, definition); AddFactory(implementations.ReaderFactories, HandlerTypes.Reader, typeArgs, definition); AddFactory(implementations.WriterFactories, HandlerTypes.Writer, typeArgs, definition); }