예제 #1
0
        /// <summary>
        /// Retrieves the worker writer for the specified type.
        /// </summary>
        /// <param name="type">The type.</param>
        /// <returns>The worker writer.</returns>
        /// <remarks>This should be called from the ContentTypeWriter.Initialize method.</remarks>
        public ContentTypeWriter GetTypeWriter(Type type, Dictionary <string, object> writerData)
        {
            if (typeWriterMap.Count == 0)
            {
                ProcessAssemblies();
            }
            ContentTypeWriter result   = null;
            var  contentTypeWriterType = typeof(ContentTypeWriter <>).MakeGenericType(type);
            Type typeWriterType;

            if (!typeWriterMap.TryGetValue(contentTypeWriterType, out typeWriterType))
            {
                var inputTypeDef = type.GetGenericTypeDefinition();

                Type chosen = null;
                foreach (var kvp in typeWriterMap)
                {
                    var args = kvp.Key.GetGenericArguments();

                    if (args.Length == 0)
                    {
                        continue;
                    }

                    if (!args[0].IsGenericType)
                    {
                        continue;
                    }

                    // Compare generic type definition
                    var keyTypeDef = args[0].GetGenericTypeDefinition();
                    if (inputTypeDef.Equals(keyTypeDef))
                    {
                        chosen = kvp.Value;
                        break;
                    }
                }

                try
                {
                    var concreteType = type.GetGenericArguments();
                    result = (ContentTypeWriter)Activator.CreateInstance(chosen.MakeGenericType(concreteType));

                    // save it for next time.
                    typeWriterMap.Add(contentTypeWriterType, result.GetType());
                }
                catch (Exception)
                {
                    throw new ArgumentException(String.Format("Could not find ContentTypeWriter for type '{0}'", type.Name));
                }
            }
            else
            {
                result = (ContentTypeWriter)Activator.CreateInstance(typeWriterType);
            }

            if (result != null)
            {
                foreach (var param in writerData)
                {
                    var propInfo = typeWriterType.GetProperty(param.Key, BindingFlags.FlattenHierarchy | BindingFlags.Public | BindingFlags.Instance);
                    if (propInfo == null || propInfo.GetSetMethod(false) == null)
                    {
                        continue;
                    }

                    if (propInfo.PropertyType.IsInstanceOfType(param.Value))
                    {
                        propInfo.SetValue(result, param.Value, null);
                    }
                    else
                    {
                        // find a type converter for this property
                        var typeConverter = TypeDescriptor.GetConverter(propInfo.PropertyType);
                        if (typeConverter.CanConvertFrom(param.Value.GetType()))
                        {
                            var propValue = typeConverter.ConvertFrom(null, CultureInfo.InvariantCulture, param.Value);
                            propInfo.SetValue(result, propValue, null);
                        }
                    }
                }

                MethodInfo dynMethod = result.GetType().GetMethod("Initialize", BindingFlags.Public | BindingFlags.Instance);
                dynMethod.Invoke(result, new object[] { _typeWriterManager });
            }
            return(result);
        }
예제 #2
0
 public void WriteRawObject <T>(T value, ContentTypeWriter writer)
 {
     writer.Write(this, value);
 }
예제 #3
0
        public ExternalReferenceContent <T> BuildContent <T>(string filename,
                                                             out object content,
                                                             string importerName = null,
                                                             Dictionary <string, object> importerData = null,
                                                             string processorName = null,
                                                             Dictionary <string, object> processorData = null,
                                                             string writerName = null,
                                                             Dictionary <string, object> writerData = null,
                                                             bool ignoreBuildItem = false)
        {
            if (IsBuiltin(filename))
            {
                content = null;
                string outputname = _buildOptions.GetOutputFilename(typeof(T), filename);
                return(new ExternalReferenceContent <T>(filename));
            }

            if (!Path.IsPathRooted(filename))
            {
                filename = _processorContext.GetFilenamePath(filename);
            }

            if (!ignoreBuildItem && _buildSource.HasBuildItem(filename))
            {
                // if there is a build item for this item leave it up to the build source to generate the actual build, and just return a ExternalReferenceContent item.
                content = null;
                string outputname = _buildOptions.GetOutputFilename(typeof(T), filename);
                outputname = _contentSaver.GetPath(outputname, typeof(T));
                return(new ExternalReferenceContent <T>(outputname));
            }

            // first find out the output type of the processor
            IContentImporter importer;

            if ((importer = CreateImporter(importerName ?? FindImporterByExtension(Path.GetExtension(filename)), importerData ?? new Dictionary <string, object>())) == null)
            {
                throw new ContentLoadException(importerName != null ?
                                               string.Format("Importer {0} not found.", importerName) :
                                               string.Format("Importer not found that handles extension {0}", Path.GetExtension(filename)));
            }
            IContentProcessor processor;

            if ((processor = CreateProcessor(processorName ?? FindDefaultProcessor(importer.GetType()), processorData ?? new Dictionary <string, object>())) == null)
            {
                throw new ContentLoadException(processorName != null ?
                                               string.Format("Processor {0} not found.", processorName) :
                                               string.Format("Processor not found that handles type {0}", importer.GetType().Name));
            }

            _processorContext.PushDirectory(Path.GetDirectoryName(filename));

            using (FileStream stream = File.OpenRead(filename))
            {
                content = importer.Import(stream, this);
            }

            content = processor.Process(content, _processorContext);

            _processorContext.PopDirectory();

            object outName;

            if (!(content is ContentItem) || !((ContentItem)content).OpaqueData.TryGetValue("OutputFileName", out outName))
            {
                outName = filename;
            }
            string outputFilename = _buildOptions.GetOutputFilename(content.GetType(), (string)outName);

            if (!_buildOptions.ForceRebuild && _contentSaver.GetLastModified(outputFilename, content.GetType()) > File.GetLastWriteTime(filename))
            {
                return(new ExternalReferenceContent <T>(_contentSaver.GetPath(outputFilename, processor.OutputType)));
            }

            ContentTypeWriter typeWriter = GetTypeWriter(writerName, content.GetType(), writerData);

            if (typeWriter == null && (typeWriter = GetTypeWriter(content.GetType(), writerData ?? new Dictionary <string, object>())) == null)
            {
                throw new ContentLoadException(string.Format("ContentTypeWriter not found for content type {0}", content.GetType()));
            }

            if (_typeWriterManager == null)
            {
                _typeWriterManager = new ContentTypeWriterManager();
            }
            using (MemoryStream stream = new MemoryStream())
            {
                ContentWriter writer = CreateWriter(_typeWriterManager, stream, _buildOptions.CompressOutput, _buildOptions.GetIdentifierString(content.GetType()));
                writer.WriteObject(content, typeWriter);
                writer.Flush();

                string path = _contentSaver.Save(stream, outputFilename, content.GetType());
                return(new ExternalReferenceContent <T>(path));
            }
        }
예제 #4
0
 public void RegisterTypeWriter <T>(ContentTypeWriter writer)
 {
     RegisterTypeWriter(typeof(T), writer);
 }